Table of Contents
使用 PHP 消息队列实现 Android 与 Web 通信
Home php教程 php手册 使用 PHP 消息队列实现 Android 与 Web 通信

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

Jun 13, 2016 am 09:04 AM
information queue

使用 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;
  }
Copy after login

然后是发送消息

    public void sendMsg(String data){
        if(!connected || socket == null) return;
        synchronized (socket) {
            try {
                out.println(data);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
Copy after login

完成后还需要关闭 socket

    private void closeSocket(){
        if(  socket == null) return;
        try {
            socket.close();
            out.close();
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        socket = null;
        connected = false;
    }
Copy after login

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

下面是服务器 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);  
	
}
Copy after login

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

脚本主程序这么写。

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

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

function handleData($dataStr, $msg_queue){
	msg_send($msg_queue,1,$dataStr);
}
Copy after login
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);

?-->
Copy after login

这样一来,其他进程就可以通过 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);
}
Copy after login


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

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

那么这个 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);
}

?-->
Copy after login

 

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

php socket.php

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

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

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

 

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to swipe right and reply quickly in iMessage on iOS 17 How to swipe right and reply quickly in iMessage on iOS 17 Sep 20, 2023 am 10:45 AM

How to Use Swipe to Reply in iMessages on iPhone Note: The Swipe to Reply feature only works with iMessage conversations in iOS 17, not regular SMS conversations in the Messages app. Open the Messages app on your iPhone. Then, head to the iMessage conversation and simply swipe right on the iMessage you want to reply to. Once this is done, the selected iMessage will be in focus while all other messages will be blurred in the background. You'll see a text box for typing a reply and a "+" icon for accessing iMessage apps like Check-ins, Places, Stickers, Photos, and more. Just enter your message,

What does it mean when a message has been sent but rejected by the other party? What does it mean when a message has been sent but rejected by the other party? Mar 07, 2024 pm 03:59 PM

The message has been sent but rejected by the other party. This means that the sent information has been successfully sent from the device, but for some reason, the other party did not receive the message. More specifically, this is usually because the other party has set certain permissions or taken certain actions, which prevents your information from being received normally.

iOS 17: How to use emojis as stickers in Messages iOS 17: How to use emojis as stickers in Messages Sep 18, 2023 pm 05:13 PM

In iOS17, Apple has added several new features to its Messages app to make communicating with other Apple users more creative and fun. One of the features is the ability to use emojis as stickers. Stickers have been around in the Messages app for years, but so far, they haven't changed much. This is because in iOS17, Apple treats all standard emojis as stickers, allowing them to be used in the same way as actual stickers. This essentially means you're no longer limited to inserting them into conversations. Now you can also drag them anywhere on the message bubble. You can even stack them on top of each other to create little emoji scenes. The following steps show you how it works in iOS17

The message has been sent but was rejected by the other party. Should I block it or delete it? The message has been sent but was rejected by the other party. Should I block it or delete it? Mar 12, 2024 pm 02:41 PM

1. Being added to the blacklist: The message has been sent but rejected by the other party. Generally, you have been blacklisted. At this time, you will not be able to send messages to the other party, and the other party will not be able to receive your messages. 2. Network problems: If the recipient's network condition is poor or there is a network failure, the message may not be successfully received. At this point, you can try to wait for the network to return to normal before sending the message again. 3. The other party has set up Do Not Disturb: If the recipient has set up Do Not Disturb in WeChat, the sender’s messages will not be reminded or displayed within a certain period of time.

How to set up Xiaomi Mi 14 Pro to light up the screen for messages? How to set up Xiaomi Mi 14 Pro to light up the screen for messages? Mar 18, 2024 pm 12:07 PM

Xiaomi 14Pro is a flagship model with excellent performance and configuration. It has achieved high sales since its official release. Many small functions of Xiaomi 14Pro will be ignored by everyone. For example, it can be set to light up the screen for messages. Although the function is small, , but it is very practical. Everyone will encounter various problems when using the mobile phone. So how to set up the Xiaomi 14Pro to light up the screen for messages? How to set up Xiaomi Mi 14 Pro to light up the screen for messages? Step 1: Open your phone’s Settings app. Step 2: Swipe down until you find the &quot;Lock screen and password&quot; option and click to enter. Step 3: In the &quot;Lock screen &amp; passcode&quot; menu, find and click the &quot;Turn on screen for notifications&quot; option. Step 4: On the &quot;Turn on screen when receiving notifications&quot; page, turn on the switch to enable

Application of queue technology in message delay and message retry in PHP and MySQL Application of queue technology in message delay and message retry in PHP and MySQL Oct 15, 2023 pm 02:26 PM

Application summary of queue technology in message delay and message retry in PHP and MySQL: With the continuous development of web applications, the demand for high concurrency processing and system reliability is getting higher and higher. As a solution, queue technology is widely used in PHP and MySQL to implement message delay and message retry functions. This article will introduce the application of queue technology in PHP and MySQL, including the basic principles of queues, methods of using queues to implement message delay, and methods of using queues to implement message retries, and give

How to edit messages on iPhone How to edit messages on iPhone Dec 18, 2023 pm 02:13 PM

The native Messages app on iPhone lets you easily edit sent texts. This way, you can correct your mistakes, punctuation, and even autocorrect wrong phrases/words that may have been applied to your text. In this article, we will learn how to edit messages on iPhone. How to Edit Messages on iPhone Required: iPhone running iOS16 or later. You can only edit iMessage text on the Messages app, and then only within 15 minutes of sending the original text. Non-iMessage text is not supported, so they cannot be retrieved or edited. Launch the Messages app on your iPhone. In Messages, select the conversation from which you want to edit the message

Analysis and optimization strategies for Java Queue queue performance Analysis and optimization strategies for Java Queue queue performance Jan 09, 2024 pm 05:02 PM

Performance Analysis and Optimization Strategy of JavaQueue Queue Summary: Queue (Queue) is one of the commonly used data structures in Java and is widely used in various scenarios. This article will discuss the performance issues of JavaQueue queues from two aspects: performance analysis and optimization strategies, and give specific code examples. Introduction Queue is a first-in-first-out (FIFO) data structure that can be used to implement producer-consumer mode, thread pool task queue and other scenarios. Java provides a variety of queue implementations, such as Arr

See all articles