ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、视频、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
Workerman\Protocols\Websocket ``` // BINARY_TYPE_BLOB Websocket blob type. // BINARY_TYPE_BLOB_DEFLATE Websocket blob type. // BINARY_TYPE_ARRAYBUFFER Websocket arraybuffer type. // BINARY_TYPE_ARRAYBUFFER_DEFLATE Websocket arraybuffer type. // ::input($buffer, ConnectionInterface $connection):int Check the integrity of the package. // ::encode($buffer, ConnectionInterface $connection):string Websocket encode. // ::decode($buffer, ConnectionInterface $connection):strng Websocket decode // ::inflate($connection, $buffer, $is_fin_frame):false|string Inflate // ::deflate($connection, $buffer):false|string Deflate // ::dealHandshake($buffer, $connection):int Websocket handshake. ``` ``` <?php //ini_set('display_errors', 'on'); //运行: php start.php start use Workerman\Worker; use Workerman\Connection\TcpConnection; if(strpos(strtolower(PHP_OS), 'win') === 0) { exit("start.php 入口不支持windows\n"); } // 检查扩展 if(!extension_loaded('pcntl')) { exit("Please install pcntl extension. See http://doc3.workerman.net/appendices/install-extension.html\n"); } if(!extension_loaded('posix')) { exit("请安装 posix 扩展. 查看http://doc3.workerman.net/appendices/install-extension.html\n"); } require_once __DIR__ . '/vendor/autoload.php'; $global_uid = 0; // 当客户端连上来时分配uid,并保存连接,并通知所有客户端 function handle_connection($connection) { global $text_worker, $global_uid; // 为这个连接分配一个uid $connection->uid = ++$global_uid; foreach($text_worker->connections as $conn) { $conn->send("user_{$connection->uid} connection,IP:".getIP()."!!\n"); } } // 当客户端发送消息过来时,转发给所有人 function handle_message(TcpConnection $connection, $data) { global $text_worker; foreach($text_worker->connections as $conn) { $conn->send("user_{$connection->uid} said: $data"); } } // 当客户端断开时,广播给所有客户端(群发) function handle_close($connection) { global $text_worker; foreach($text_worker->connections as $conn) { $conn->send("user_{$connection->uid} logout"); } } function getIP() { static $realip; if (isset($_SERVER)){ if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])){ $realip = $_SERVER["HTTP_X_FORWARDED_FOR"]; } else if (isset($_SERVER["HTTP_CLIENT_IP"])) { $realip = $_SERVER["HTTP_CLIENT_IP"]; } else { $realip = $_SERVER["REMOTE_ADDR"]; } } else { if (getenv("HTTP_X_FORWARDED_FOR")){ $realip = getenv("HTTP_X_FORWARDED_FOR"); } else if (getenv("HTTP_CLIENT_IP")) { $realip = getenv("HTTP_CLIENT_IP"); } else { //如果 PHP 脚本不是通过 HTTP 请求运行的(例如在命令行中运行),$_SERVER['REMOTE_ADDR'] 将不存在。 $realip = getenv("REMOTE_ADDR")??'0.0.0.0'; } } // ip2long($ip_address); // long2ip($proper_address); return $realip; } // 创建一个文本协议的Worker主进程监听2347接口websocket,如果时前端websockt则必须是websocket,如果telnet 127.0.0.1 2347则可以是其它协议 $text_worker = new Worker("websocket://0.0.0.0:2347"); // 只启动多个子进程,每个子进程可以和多个客户端链接,这样方便客户端之间传输数据 //此示例进程数只能选择1,因为进程间的客户端是隔离的,无法直接通讯,也就是A进程中无法直接操作B进程的客户端connection对象发送数据。(要做到这点,需要进程间通讯,比如可以使用Channel组件,例如例子-集群发送、例子-分组发送)。 $text_worker->count = 1; $text_worker->onConnect = 'handle_connection'; $text_worker->onMessage = 'handle_message'; $text_worker->onClose = 'handle_close'; // 每个进程启动后打印当前进程id编号即 $worker1->id $text_worker->onWorkerStart = function($text_worker) { echo $text_worker->id;//输出0,1,2,3 }; Worker::runAll(); ``` <!doctype html> <html lang="en"> <head cache-control=''> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>websocket</title> </head> <body> <input id="text" value=""> <input type="submit" value="send" onclick="start()"> <input type="submit" value="close" onclick="close()"> <div id="msg"></div> <script> /** 0:未连接 1:连接成功,可通讯 2:正在关闭 3:连接已关闭或无法打开 */ //创建一个webSocket 实例 var webSocket = new WebSocket("ws://8.137.80.185:2347"); webSocket.onerror = function (event){ console.log(event) onError(event); }; // 打开websocket webSocket.onopen = function (event){ onOpen(event); }; //监听消息 webSocket.onmessage = function (event){ onMessage(event); }; webSocket.onclose = function (event){ onClose(event); } //关闭监听websocket function onError(event){ document.getElementById("msg").innerHTML = "<p>close</p>"; console.log("error"+event.data); }; function onOpen(event){ console.log("open:"+sockState()); document.getElementById("msg").innerHTML = "<p>Connect to Service</p>"; }; function onMessage(event){ console.log("onMessage"); console.log(event); document.getElementById("msg").innerHTML += "<p>response:"+event.data+"</p>" }; function onClose(event){ document.getElementById("msg").innerHTML = "<p>close</p>"; console.log("close:"+sockState()); webSocket.close(); } function sockState(){ var status = ['未连接','连接成功,可通讯','正在关闭','连接已关闭或无法打开']; return status[webSocket.readyState]; } function start(event){ console.log(webSocket); var msg = document.getElementById('text').value; document.getElementById('text').value = ''; console.log(sockState()); console.log("发送msg:"+msg); if(webSocket.readyState===0){ return "未连接"; }else if(webSocket.readyState===1){ webSocket.send("发送msg:"+msg); }else if(webSocket.readyState===2){ return "正在关闭"; }else{ return "连接已关闭或链接失败"; } document.getElementById("msg").innerHTML += "<p>request:"+msg+"</p>" }; function close(event){ webSocket.close(); } </script> </body> </html> ``` ```