使用 PHP 消息队列实现 Android 与 Web 通信_PHP教程
使用 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; }
然后是发送消息
public void sendMsg(String data){ if(!connected || socket == null) return; synchronized (socket) { try { out.println(data); } catch (Exception e) { e.printStackTrace(); } } }
完成后还需要关闭 socket
private void closeSocket(){ if( socket == null) return; try { socket.close(); out.close(); br.close(); } catch (IOException e) { e.printStackTrace(); } socket = null; connected = false; }
注意这些方法都不要在主线程执行。
下面是服务器 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); }
也比较简单。这个进程是独立运行的,那么打开网页请求数据,需要从另一段脚本接入,下面就需要用到进程间通信,我选择消息队列,也就是上面的 $msg_queue 变量。
脚本主程序这么写。
$msg_queue_key = ftok(__FILE__,'socket'); //__FILE__ 指当前文件名字 $msg_queue = msg_get_queue($msg_queue_key); //获取已有的或者新建一个消息队列 buildSocket($msg_queue); socket_close($sock);
那么handleData() 的任务就是把收到的消息放到队列里面去
function handleData($dataStr, $msg_queue){ msg_send($msg_queue,1,$dataStr); }
<!--?php //socket.php 服务器进程 function buildSocket($msg_queue){ } function handleData($dataStr, $msg_queue){ } set_time_limit(0); $msg_queue_key = ftok(__FILE__,'socket'); $msg_queue = msg_get_queue($msg_queue_key); buildSocket($msg_queue); socket_close($sock); ?-->
这样一来,其他进程就可以通过 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", 'socket'); //第一个变量为上方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); }
现在就差最后一步,如何主动把数据发往前端?这要用到 HTML5 的新特性:服务器发送事件(要使用较新的非 IE 浏览器,具体查看这里)。直接看JS代码
var source = new EventSource("php/getData.php"); //Web 服务器路径 source.onmessage = function(event){ //消息事件回调 var resData = event.data; document.getElementById("res").innerHTML=resData; };
那么这个 getData.php 就是上面那个从消息队列获取数据的脚本。只是为了让它被识别为服务器事件,需要加一点格式上的说明,具体如下。
<!--?php //getData.php,提供给 Web 请求使用。 //声明文档类型 header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); 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", 'socket'); $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); } ?-->
下面就可以开始运行,首先运行服务器
php socket.php
打印了 listening 就可以使用 Android 设备连接了。
然后再用 Web 上 JS 请求 getData 脚本,请求后前台可以不断地获得新的数据。需要注意的是消息队列可能会阻塞(消息量达到上限),再有就是 JS 本身消息机制的限制,因此丢失,延迟等现象频发。
Web 通信的老问题就是稳定性。以前老是怨恨 Web QQ 掉包,其实整个 Web 革命尚未成功。

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











메시지가 전송되었지만 상대방이 거부했습니다. 이는 보낸 정보가 장치에서 성공적으로 전송되었지만 어떤 이유로 상대방이 메시지를 받지 못했음을 의미합니다. 보다 구체적으로 말하면, 이는 일반적으로 상대방이 특정 권한을 설정하거나 특정 조치를 취함으로써 귀하의 정보가 정상적으로 수신되지 않는 경우가 많습니다.

iPhone의 iMessage에서 밀어서 답장하는 방법 참고: 밀어서 답장 기능은 메시지 앱의 일반 SMS 대화가 아닌 iOS 17의 iMessage 대화에서만 작동합니다. iPhone에서 메시지 앱을 엽니다. 그런 다음 iMessage 대화로 이동하여 답장하려는 iMessage를 오른쪽으로 스와이프하면 됩니다. 이 작업이 완료되면 선택한 iMessage에 초점이 맞춰지고 다른 모든 메시지는 배경에서 흐려집니다. 답장을 입력하기 위한 텍스트 상자와 체크인, 장소, 스티커, 사진 등과 같은 iMessage 앱에 접근하기 위한 "+" 아이콘이 표시됩니다. 메시지를 입력하시면 됩니다.

iOS17에서 Apple은 다른 Apple 사용자와 더욱 창의적이고 재미있게 소통할 수 있도록 메시지 앱에 몇 가지 새로운 기능을 추가했습니다. 기능 중 하나는 이모티콘을 스티커로 사용할 수 있는 기능입니다. 스티커는 수년 동안 메시지 앱에 사용되었지만 지금까지는 크게 바뀌지 않았습니다. iOS17에서는 Apple이 모든 표준 이모티콘을 스티커로 취급하여 실제 스티커와 동일한 방식으로 사용할 수 있기 때문입니다. 이는 본질적으로 더 이상 대화에 삽입하는 데 국한되지 않는다는 것을 의미합니다. 이제 메시지 풍선의 어느 곳으로나 드래그할 수도 있습니다. 서로 쌓아서 작은 이모티콘 장면을 만들 수도 있습니다. 다음 단계는 iOS17에서 작동하는 방식을 보여줍니다.

1. 블랙리스트에 추가됨: 메시지가 전송되었지만 상대방이 거부했습니다. 일반적으로 블랙리스트에 등록된 상태에서는 상대방에게 메시지를 보낼 수 없습니다. 메시지를 받을 수 있습니다. 2. 네트워크 문제: 수신자의 네트워크 상태가 좋지 않거나 네트워크 장애가 있는 경우 메시지가 성공적으로 수신되지 않을 수 있습니다. 이 시점에서 메시지를 다시 보내기 전에 네트워크가 정상으로 돌아올 때까지 기다릴 수 있습니다. 3. 상대방이 방해 금지 모드를 설정한 경우: 수신자가 WeChat에서 방해 금지 모드를 설정한 경우 보낸 사람의 메시지는 일정 시간 동안 알림을 받거나 표시되지 않습니다.

iPhone의 기본 메시지 앱을 사용하면 보낸 문자를 쉽게 편집할 수 있습니다. 이렇게 하면 실수, 구두점을 수정할 수 있으며 텍스트에 적용될 수 있는 잘못된 문구/단어도 자동으로 수정할 수 있습니다. 이번 포스팅에서는 아이폰에서 메시지를 편집하는 방법에 대해 알아 보겠습니다. iPhone에서 메시지를 편집하는 방법 필수: iOS16 이상을 실행하는 iPhone. 메시지 앱에서만 iMessage 텍스트를 편집할 수 있으며, 원본 텍스트를 보낸 후 15분 이내에만 가능합니다. iMessage가 아닌 텍스트는 지원되지 않으므로 검색하거나 편집할 수 없습니다. iPhone에서 메시지 앱을 실행하세요. 메시지에서 메시지를 편집하려는 대화를 선택하세요.

샤오미 14Pro는 뛰어난 성능과 구성을 갖춘 플래그십 모델로, 공식 출시 이후 높은 판매량을 달성했습니다. 예를 들어, 샤오미 14Pro의 많은 작은 기능은 메시지를 표시하도록 설정할 수 있습니다. 기능은 작지만 매우 실용적입니다. 휴대전화를 사용할 때 누구나 다양한 문제에 직면하게 됩니다. 그러면 메시지 화면을 켜도록 Xiaomi 14Pro를 설정하는 방법은 무엇입니까? 메시지 화면을 밝히도록 Xiaomi 14Pro를 설정하는 방법은 무엇입니까? 1단계: 휴대전화의 설정 앱을 엽니다. 2단계: "잠금 화면 및 비밀번호" 옵션을 찾을 때까지 아래로 스와이프하고 클릭하여 들어갑니다. 3단계: "잠금 화면 및 비밀번호" 메뉴에서 "알림 화면 켜기" 옵션을 찾아서 클릭하세요. 4단계: '알림 수신 시 화면 켜기' 페이지에서 스위치를 켜서 활성화합니다.

PHP 및 MySQL의 메시지 지연 및 메시지 재시도에 대한 큐 기술 적용 요약: 웹 애플리케이션의 지속적인 개발로 인해 높은 동시 처리 및 시스템 안정성에 대한 요구가 점점 더 높아지고 있습니다. 이에 대한 해결책으로 큐 기술은 메시지 지연 및 메시지 재시도 기능을 구현하기 위해 PHP 및 MySQL에서 널리 사용됩니다. 이 기사에서는 큐의 기본 원리, 큐를 사용하여 메시지 지연을 구현하는 방법, 큐를 사용하여 메시지 재시도를 구현하는 방법을 포함하여 PHP 및 MySQL의 큐 기술 적용을 소개하고 다음을 제공합니다.

JavaQueue의 성능 분석 및 최적화 전략 큐 요약: 큐(Queue)는 Java에서 일반적으로 사용되는 데이터 구조 중 하나이며 다양한 시나리오에서 널리 사용됩니다. 이 기사에서는 성능 분석 및 최적화 전략이라는 두 가지 측면에서 JavaQueue 대기열의 성능 문제를 논의하고 특정 코드 예제를 제공합니다. 소개 큐는 생산자-소비자 모드, 스레드 풀 작업 큐 및 기타 시나리오를 구현하는 데 사용할 수 있는 FIFO(선입선출) 데이터 구조입니다. Java는 Arr과 같은 다양한 대기열 구현을 제공합니다.
