服務器
<?php
use Workerman\Worker;
require_once './Workerman/Autoloader.php';
// 初始化一個worker容器,監(jiān)聽1234端口
$worker = new Worker('websocket://127.0.0.1:1234');
/*
* 注意這里進程數(shù)必須設置為1,否則會報端口占用錯誤
* (php 7可以設置進程數(shù)大于1,前提是$inner_text_worker->reusePort=true)
*/
$worker->count = 1;
// worker進程啟動后創(chuàng)建一個text Worker以便打開一個內部通訊端口
$worker->onWorkerStart = function($worker)
{
// 開啟一個內部端口,方便內部系統(tǒng)推送數(shù)據(jù),Text協(xié)議格式 文本+換行符
$inner_text_worker = new Worker('text://127.0.0.1:5678');
$inner_text_worker->onMessage = function($connection, $buffer)
{
global $worker;
// $data數(shù)組格式,里面有uid,表示向那個uid的頁面推送數(shù)據(jù)
$data = json_decode($buffer, true);
$uid = $data;
// 通過workerman,向uid的頁面推送數(shù)據(jù)
$ret = sendMessageByUid($uid, $buffer);
// 返回推送結果
$connection->send($ret ? 'ok' : 'fail');
};
// 執(zhí)行監(jiān)聽
$inner_text_worker->listen();
};
// 新增加一個屬性,用來保存uid到connection的映射
$worker->uidConnections = array();
// 當有客戶端發(fā)來消息時執(zhí)行的回調函數(shù)
$worker->onMessage = function($connection, $data)use($worker)
{
// 判斷當前客戶端是否已經驗證,既是否設置了uid
if(!isset($connection->uid))
{
// 沒驗證的話把第一個包當做uid(這里為了方便演示,沒做真正的驗證)
$connection->uid = $data;
/* 保存uid到connection的映射,這樣可以方便的通過uid查找connection,
* 實現(xiàn)針對特定uid推送數(shù)據(jù)
*/
$worker->uidConnections = $connection;
return;
}
};
// 當有客戶端連接斷開時
$worker->onClose = function($connection)use($worker)
{
global $worker;
if(isset($connection->uid))
{
// 連接斷開時刪除映射
unset($worker->uidConnections);
}
};
// 向所有驗證的用戶推送數(shù)據(jù)
function broadcast($message)
{
global $worker;
foreach($worker->uidConnections as $connection)
{
$connection->send($message);
}
}
// 針對uid推送數(shù)據(jù)
function sendMessageByUid($uid, $message)
{
global $worker;
if(isset($worker->uidConnections))
{
$connection = $worker->uidConnections;
$connection->send($message);
return true;
}
return false;
}
// 運行所有的worker
Worker::runAll();
客戶端
<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
//ws.send('hello world');
function connect(){
var ws =new WebSocket('ws://127.0.0.1:1234');
ws.onpen=function(){
var uid ='uid1';alert(uid);
ws.send(uid);
};
ws.onmessage=function(e){
alert(e.data);
}
}
</script>
</head>
<body onload="connect();">
<div>TODO write content</div>
</body>
</html>