workerman使用记录
WebSocket通讯协议配置
start_gateway.php文件配置
$gateway = new Gateway("websocket://0.0.0.0:8282"); |
WebSocket protocol 是HTML5一种新的协议。它实现了浏览器与服务器全双工通信
客户端新建一个WebSocket
socket = new WebSocket("ws://127.0.0.1:8282"); |
连接回调事件
客户端:
WebSocket.onopen属性定义一个事件处理程序,当WebSocket 的连接状态readyState 变为“OPEN”时调用;这意味着当前连接已经准备好发送和接受数据。这个事件处理程序通过 事件(建立连接时)触发。
socket.onopen = function() { $("#msg").html("连接成功..."); }; |
服务器端:
public static function onConnect($client_id) { // 向当前client_id发送数据 Gateway::sendToClient($client_id, "Hello $client_id\r\n"); // 向所有人发送 Gateway::sendToAll("$client_id login\r\n"); } |
客户端发送信息和服务器端接收信息
客户端:
socket.send('水电费'); |
服务器端:
public static function onMessage($client_id, $message) { var_dump($message); //水电费 // 向所有人发送 Gateway::sendToAll("$client_id said $message\r\n"); } |
浏览器每次连接都是一个新的连接
主动往客户端推送信息
require_once 'GatewayWorker\Gateway.php'; use \GatewayClient\Gateway; Gateway::$registerAddress = '127.0.0.1:1238'; Gateway::sendToAll('hello'); //向所有连接广播消息 |
与ThinkPHP等框架结合
现有mvc框架项目与GatewayWorker独立部署互不干扰
所有的业务逻辑都由网站页面post/get到mvc框架中完成
GatewayWorker不接受客户端发来的数据,即GatewayWorker不处理任何业务逻辑,GatewayWorker仅仅当做一个单向的推送通道
仅当mvc框架需要向浏览器主动推送数据时才在mvc框架中调用Gateway的API(GatewayClient)完成推送
具体实现步骤
1、网站页面建立与GatewayWorker的websocket连接
2、GatewayWorker发现有页面发起连接时,将对应连接的client_id发给网站页面
3、网站页面收到client_id后触发一个ajax请求(假设是bind.php)将client_id发到mvc后端
4、mvc后端bind.php收到client_id后利用GatewayClient调用Gateway::bindUid($client_id, $uid)将client_id与当前uid(用户id或者客户端唯一标识)绑定。如果有群组、群发功能,也可以利用Gateway::joinGroup($client_id, $group_id)将client_id加入到对应分组
5、页面发起的所有请求都直接post/get到mvc框架统一处理,包括发送消息
6、mvc框架处理业务过程中需要向某个uid或者某个群组发送数据时,直接调用GatewayClient的接口Gateway::sendToUid Gateway::sendToGroup 等发送即可
Event.php文件
public static function onConnect($client_id) { Gateway::sendToClient($client_id, json_encode(array( 'type' => 'init', 'client_id' => $client_id ))); } |
当客户端打开一个websocket连接时,就会接接收到如下信息:
{"type":"init","client_id":"7f0000010b5400000001"}
websoket.html
ws = new WebSocket("ws://127.0.0.1:8282"); // 服务端主动推送消息时会触发这里的onmessage ws.onmessage = function(e){ console.log(e) // {isTrusted: true, data: "{"type":"init","client_id":"7f0000010b5400000001"}", origin: "ws://127.0.0.1:8282", lastEventId: "", source: null, …} // json数据转换成js对象 var data = eval("("+e.data+")"); var type = data.type || ''; switch(type){ // Events.php中返回的init类型的消息,将client_id发给后台进行uid绑定 case 'init': // 利用jquery发起ajax请求,将client_id发给后端进行uid绑定 $.post('./bind.php', {client_id: data.client_id}, function(data){}, 'json'); break; // 当mvc框架调用GatewayClient发消息时直接alert出来 default : alert(e.data); } }; |
bind.php
require_once 'GatewayWorker\Gateway.php'; use \GatewayClient\Gateway; Gateway::$registerAddress = '127.0.0.1:1238'; $client_id = $_POST['client_id']; // client_id与uid绑定 Gateway::bindUid($client_id, $uid); // 加入某个群组(可调用多次加入多个群组) Gateway::joinGroup($client_id, $group_id); |