Jadual Kandungan
使用 PHP 消息队列实现 Android 与 Web 通信
Rumah php教程 php手册 使用 PHP 消息队列实现 Android 与 Web 通信

使用 PHP 消息队列实现 Android 与 Web 通信

Jun 13, 2016 am 09:04 AM
maklumat beratur

使用 PHP 消息队列实现 Android 与 Web 通信

需求描述很简单:Android 发送数据到 Web 网页上。

系统: Ubuntu 14.04 + apache2 + php5 + Android 4.4

思路是 socket + 消息队列 + 服务器发送事件,下面的讲解步骤为 Android 端,服务器端,前端。重点是在于 PHP 进程间通信。

Android 端比较直接,就是一个 socket 程序。需要注意的是,如果直接在活动主线程里面创建 socket 会报一个 android.os.NetworkOnMainThreadException, 因此最好的方法是开个子线程来创建 socket,代码如下

    
private Socket socket = null;
private boolean connected = false;
private PrintWriter out;
private BufferedReader br;

private void buildSocket(){
        if(socket != null)
            return;
        try {
            socket = new Socket("223.3.68.101",54311); //IP地址与端口号
            out = new PrintWriter(
                    new BufferedWriter(
                            new OutputStreamWriter(
                                    socket.getOutputStream())), true);
            br = new BufferedReader(
                    new InputStreamReader(socket.getInputStream()));
        } catch (IOException e) {
            e.printStackTrace();
        }
        connected = true;
  }
Salin selepas log masuk

然后是发送消息

    public void sendMsg(String data){
        if(!connected || socket == null) return;
        synchronized (socket) {
            try {
                out.println(data);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
Salin selepas log masuk

完成后还需要关闭 socket

    private void closeSocket(){
        if(  socket == null) return;
        try {
            socket.close();
            out.close();
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        socket = null;
        connected = false;
    }
Salin selepas log masuk

注意这些方法都不要在主线程执行。

下面是服务器 PHP 端。

首先要运行一个进程来接收信息。

function buildSocket($msg_queue){

	$address = "223.3.68.101";
	$port = 54321; 

	if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false){
		echo "socket_create() failed:" . socket_strerror(socket_last_error()) . "/n";
		die;
	}
	echo "socket create\n";

	if (socket_set_block($sock) == false){
	 echo "socket_set_block() faild:" . socket_strerror(socket_last_error()) . "\n";
	 die;
	}

	if (socket_bind($sock, $address, $port) == false){
		echo "socket_bind() failed:" . socket_strerror(socket_last_error()) . "\n";
		die;
	}

	if (socket_listen($sock, 4) == false){
		echo "socket_listen() failed:" . socket_strerror(socket_last_error()) . "\n";
		die;
	}
	echo "listening\n";
 
	if (($msgsock = socket_accept($sock)) === false) {  
		echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error()) . "\n";  
		die;  
	}  

	$buf = socket_read($msgsock, 8192);  
	while(true){
		if(strlen($buf) > 1)
			handleData($buf,$msg_queue); //见后文
		$buf = socket_read($msgsock, 8192);  
		
		//看情况 break 掉
	}
	socket_close($msgsock);  
	
}
Salin selepas log masuk

也比较简单。这个进程是独立运行的,那么打开网页请求数据,需要从另一段脚本接入,下面就需要用到进程间通信,我选择消息队列,也就是上面的 $msg_queue 变量。

脚本主程序这么写。

$msg_queue_key = ftok(__FILE__,'socket'); //__FILE__ 指当前文件名字
$msg_queue = msg_get_queue($msg_queue_key); //获取已有的或者新建一个消息队列
buildSocket($msg_queue);
socket_close($sock);
Salin selepas log masuk
其中的 ftok() 函数就是生成一个队列的 key,以区分。

那么handleData() 的任务就是把收到的消息放到队列里面去

function handleData($dataStr, $msg_queue){
	msg_send($msg_queue,1,$dataStr);
}
Salin selepas log masuk
Socket 进程脚本骨架
<!--?php
//socket.php 服务器进程
 function buildSocket($msg_queue){
}

function handleData($dataStr, $msg_queue){
}

set_time_limit(0);
$msg_queue_key = ftok(__FILE__,&#39;socket&#39;);
$msg_queue = msg_get_queue($msg_queue_key);

buildSocket($msg_queue);
socket_close($sock);

?-->
Salin selepas log masuk

这样一来,其他进程就可以通过 key 找到这个队列,从里面读取消息了。使用这样可读

function redFromQueue($message_queue){
	msg_receive($message_queue, 0, $message_type, 1024, $message, true, MSG_IPC_NOWAIT);
	echo $message."\n\n";
}

$msg_queue_key = ftok("socket.php", &#39;socket&#39;); //第一个变量为上方socket进程的文件名。
$msg_queue = msg_get_queue($msg_queue_key, 0666);

while(true){
	$msg_queue_status = msg_stat_queue($msg_queue); //获取消息队列的状态
	if($msg_queue_status["msg_qnum"] == 0) //如果此时消息队列为空,那么跳过,否则会读取空行。
		continue;
	redFromQueue($msg_queue);
}
Salin selepas log masuk


现在就差最后一步,如何主动把数据发往前端?这要用到 HTML5 的新特性:服务器发送事件(要使用较新的非 IE 浏览器,具体查看这里)。直接看JS代码

var source = new EventSource("php/getData.php"); //Web 服务器路径
source.onmessage = function(event){ //消息事件回调
	var resData = event.data;	
	document.getElementById("res").innerHTML=resData;
};
Salin selepas log masuk

那么这个 getData.php 就是上面那个从消息队列获取数据的脚本。只是为了让它被识别为服务器事件,需要加一点格式上的说明,具体如下。

<!--?php
//getData.php,提供给 Web 请求使用。
//声明文档类型
header(&#39;Content-Type: text/event-stream&#39;);
header(&#39;Cache-Control: no-cache&#39;);

function redFromQueue($message_queue){
	msg_receive($message_queue, 0, $message_type, 1024, $message, true, MSG_IPC_NOWAIT);
	echo "data:".$message."\n\n"; //注意一定要在数据前面加上 “data:”
	flush(); //立刻 flush 一下
}

$msg_queue_key = ftok("socket.php", &#39;socket&#39;);
$msg_queue = msg_get_queue($msg_queue_key, 0666);

echo "data:connected\n\n";
flush();

while(true){
	$msg_queue_status = msg_stat_queue($msg_queue);
	if($msg_queue_status["msg_qnum"] == 0)
		continue;

	redFromQueue($msg_queue);
}

?-->
Salin selepas log masuk

 

下面就可以开始运行,首先运行服务器

php socket.php

打印了 listening 就可以使用 Android 设备连接了。

然后再用 Web 上 JS 请求 getData 脚本,请求后前台可以不断地获得新的数据。需要注意的是消息队列可能会阻塞(消息量达到上限),再有就是 JS 本身消息机制的限制,因此丢失,延迟等现象频发。

Web 通信的老问题就是稳定性。以前老是怨恨 Web QQ 掉包,其实整个 Web 革命尚未成功。

 

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Akan R.E.P.O. Ada Crossplay?
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Apakah yang dimaksudkan apabila mesej telah dihantar tetapi ditolak oleh pihak lain? Apakah yang dimaksudkan apabila mesej telah dihantar tetapi ditolak oleh pihak lain? Mar 07, 2024 pm 03:59 PM

Mesej telah dihantar tetapi ditolak oleh pihak lain Ini bermakna maklumat yang dihantar telah berjaya dihantar daripada peranti, tetapi atas sebab tertentu, pihak lain tidak menerima mesej tersebut. Secara lebih khusus, ini biasanya kerana pihak lain telah menetapkan kebenaran tertentu atau mengambil tindakan tertentu, yang menghalang maklumat anda daripada diterima secara normal.

Cara meleret ke kanan dan membalas dengan cepat dalam iMessage pada iOS 17 Cara meleret ke kanan dan membalas dengan cepat dalam iMessage pada iOS 17 Sep 20, 2023 am 10:45 AM

Cara Menggunakan Leret untuk Membalas dalam iMessages pada iPhone Nota: Ciri Leret untuk Membalas hanya berfungsi dengan perbualan iMessage dalam iOS 17, bukan perbualan SMS biasa dalam apl Messages. Buka apl Mesej pada iPhone anda. Kemudian, pergi ke perbualan iMessage dan hanya leret ke kanan pada iMessage yang ingin anda balas. Setelah ini dilakukan, iMessage yang dipilih akan menjadi fokus manakala semua mesej lain akan kabur di latar belakang. Anda akan melihat kotak teks untuk menaip balasan dan ikon "+" untuk mengakses apl iMessage seperti Daftar Masuk, Tempat, Pelekat, Foto dan banyak lagi. Hanya masukkan mesej anda,

iOS 17: Cara menggunakan emoji sebagai pelekat dalam Messages iOS 17: Cara menggunakan emoji sebagai pelekat dalam Messages Sep 18, 2023 pm 05:13 PM

Dalam iOS17, Apple telah menambah beberapa ciri baharu pada apl Mesejnya untuk menjadikan komunikasi dengan pengguna Apple lain lebih kreatif dan menyeronokkan. Salah satu cirinya ialah keupayaan untuk menggunakan emoji sebagai pelekat. Pelekat telah wujud dalam apl Mesej selama bertahun-tahun, tetapi setakat ini, ia tidak banyak berubah. Ini kerana dalam iOS17, Apple menganggap semua emoji standard sebagai pelekat, membolehkan ia digunakan dengan cara yang sama seperti pelekat sebenar. Ini pada asasnya bermakna anda tidak lagi terhad untuk memasukkannya ke dalam perbualan. Kini anda juga boleh menyeretnya ke mana-mana sahaja pada gelembung mesej. Anda juga boleh menyusunnya di atas satu sama lain untuk mencipta adegan emoji kecil. Langkah berikut menunjukkan kepada anda cara ia berfungsi dalam iOS17

Mesej telah dihantar tetapi telah ditolak oleh pihak lain Adakah saya patut menyekatnya atau memadamnya? Mesej telah dihantar tetapi telah ditolak oleh pihak lain Adakah saya patut menyekatnya atau memadamnya? Mar 12, 2024 pm 02:41 PM

1. Ditambah pada senarai hitam: Jika mesej telah dihantar tetapi ditolak oleh pihak yang satu lagi, ia biasanya disenaraihitamkan Pada masa ini, anda tidak akan dapat menghantar mesej kepada pihak yang satu lagi dan pihak yang satu lagi tidak akan dapat menerima mesej anda. 2. Masalah rangkaian: Jika keadaan rangkaian penerima kurang baik atau terdapat kegagalan rangkaian, mesej mungkin tidak berjaya diterima. Pada ketika ini, anda boleh cuba menunggu sehingga rangkaian kembali normal sebelum menghantar mesej semula. 3. Pihak satu lagi telah menyediakan Jangan Ganggu: Jika penerima telah menyediakan Jangan Ganggu dalam WeChat, mesej penghantar tidak akan diingatkan atau dipaparkan dalam tempoh masa tertentu.

Bagaimana untuk mengedit mesej pada iPhone Bagaimana untuk mengedit mesej pada iPhone Dec 18, 2023 pm 02:13 PM

Apl Mesej asli pada iPhone membolehkan anda mengedit teks yang dihantar dengan mudah. Dengan cara ini, anda boleh membetulkan kesilapan, tanda baca dan juga frasa/perkataan yang salah secara automatik yang mungkin telah digunakan pada teks anda. Dalam artikel ini, kita akan belajar cara mengedit mesej pada iPhone. Cara Mengedit Mesej pada iPhone Diperlukan: iPhone menjalankan iOS16 atau lebih tinggi. Anda hanya boleh mengedit teks iMessage pada apl Messages, dan kemudian hanya dalam masa 15 minit selepas menghantar teks asal. Teks bukan iMessage tidak disokong, jadi ia tidak boleh diambil atau diedit. Lancarkan apl Mesej pada iPhone anda. Dalam Mesej, pilih perbualan dari mana anda ingin mengedit mesej

Bagaimana untuk menyediakan Xiaomi Mi 14 Pro untuk menyalakan skrin untuk mesej? Bagaimana untuk menyediakan Xiaomi Mi 14 Pro untuk menyalakan skrin untuk mesej? Mar 18, 2024 pm 12:07 PM

Xiaomi 14Pro ialah model utama dengan prestasi dan konfigurasi yang sangat baik. Ia telah mencapai jualan yang tinggi sejak dikeluarkan secara rasmi Banyak fungsi kecil Xiaomi 14Pro akan diabaikan oleh semua orang fungsinya kecil, , tetapi sangat praktikal Setiap orang akan menghadapi pelbagai masalah apabila menggunakan telefon bimbit Jadi bagaimana untuk menyediakan Xiaomi 14Pro untuk menyalakan skrin untuk mesej. Bagaimana untuk menyediakan Xiaomi Mi 14 Pro untuk menyalakan skrin untuk mesej? Langkah 1: Buka apl Tetapan telefon anda. Langkah 2: Leret ke bawah sehingga anda menemui pilihan "Skrin kunci dan kata laluan" dan klik untuk masuk. Langkah 3: Dalam menu "Skrin kunci & kod laluan", cari dan klik pilihan "Hidupkan skrin untuk pemberitahuan". Langkah 4: Pada halaman "Hidupkan skrin apabila menerima pemberitahuan", hidupkan suis untuk mendayakan

Aplikasi teknologi baris gilir dalam kelewatan mesej dan cuba semula mesej dalam PHP dan MySQL Aplikasi teknologi baris gilir dalam kelewatan mesej dan cuba semula mesej dalam PHP dan MySQL Oct 15, 2023 pm 02:26 PM

Ringkasan aplikasi teknologi baris gilir dalam kelewatan mesej dan cuba semula mesej dalam PHP dan MySQL: Dengan pembangunan berterusan aplikasi web, permintaan untuk pemprosesan serentak yang tinggi dan kebolehpercayaan sistem semakin tinggi dan lebih tinggi. Sebagai penyelesaian, teknologi baris gilir digunakan secara meluas dalam PHP dan MySQL untuk melaksanakan kelewatan mesej dan fungsi cuba semula mesej. Artikel ini akan memperkenalkan aplikasi teknologi baris gilir dalam PHP dan MySQL, termasuk prinsip asas baris gilir, kaedah menggunakan baris gilir untuk melaksanakan kelewatan mesej dan kaedah menggunakan baris gilir untuk melaksanakan percubaan semula mesej, dan memberi

Analisis dan strategi pengoptimuman untuk prestasi baris gilir Java Queue Analisis dan strategi pengoptimuman untuk prestasi baris gilir Java Queue Jan 09, 2024 pm 05:02 PM

Analisis Prestasi dan Strategi Pengoptimuman JavaQueue Queue Ringkasan: Queue (Queue) ialah salah satu struktur data yang biasa digunakan di Java dan digunakan secara meluas dalam pelbagai senario. Artikel ini akan membincangkan isu prestasi baris gilir JavaQueue dari dua aspek: analisis prestasi dan strategi pengoptimuman serta memberikan contoh kod khusus. Baris Gilir Pengenalan ialah struktur data masuk dahulu keluar dahulu (FIFO) yang boleh digunakan untuk melaksanakan mod pengeluar-pengguna, baris gilir tugas kumpulan benang dan senario lain. Java menyediakan pelbagai pelaksanaan baris gilir, seperti Arr

See all articles