需要做一个 聊天室,所以需要使用到 socket 来推送服务器消息。于是想到了websocket 技术。在网上找了一下发现有一个 workman 已经封装好了PHP的socket 。所以尝试一下 用它。
下载及安装
workman下载 地址 这里我选择的是window版本
遇到的问题
根据手册安装好 workman
后开始测试功能。在使用 js客户端时,发现下面问题。
问题:WebSocket handshake: Unexpected response code: 200
var websocket = window.WebSocket || window.MozWebSocket;
var ws = new websocket("ws://127.0.0.1:3333");
ws.onopen=function(){
alert('链接成功');
ws.send('I like');
alert('发送了一个 字符串');
}
ws.onmessage = function(e){
alert('收到一条消息:'+e.data);
}
(e){
alert('收到一条消息:'+e.data);
}
错误信息:
WebSocket connection to ‘ws://127.0.0.1:3333/’ failed:
Error during WebSocket handshake: Unexpected response code: 200
解决办法
服务器配置出错。在 实例化 websocket 对象时。错误的写成了 http
正确写法:
$http_worker = new Worker('websocket://0.0.0.0:3333');
workerman 手册 6.4 测试出现错误
代码:
<?php
namespace Application;
use Workerman\Worker;
//引入 workman
require_once __DIR__.'/../WorkMan/Autoloader.php';
$global_uid = 0;
//当客户端连接上来时分配uid,并保存连接,并通知所有客户端
function handle_connection($connection){
global $text_worker,$global_uid;
$connection->uid = ++$global_uid;
}
//当客户端发送消息过来时,转发给所有人
function handle_message($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");
}
}
//创建一个 监听 4444 接口
$text_worker = new Worker("text://0.0.0.0:4444");
//只启动1个进程,这样方便客户端之间 传输数据。
$text_worker->count = 1;
$text_worker->onConnect = 'handle_connection';
$text_worker->onMessage = 'handle_message';
$text_worker->onClose = 'handle_close';
Worker::runAll();
使用 cmd 命令行 。输入 telnet 127.0.0.1 4444
打开回显功能 Ctrl + ]
在服务端,出现下面的错误。
实例:
解决办法 :
在使用 $text_worker->onConnect
时 给其赋值的 必须是一个 方法的地址。方便 call_user_func 回调。
正确 写法:(仅仅是个小例子)
<?php
namespace Application;
use Workerman\Worker;
//引入 workman
require_once __DIR__.'/../WorkMan/Autoloader.php';
$global_uid = 0;
//创建一个 监听 4444 接口
$text_worker = new Worker("text://0.0.0.0:4444");
//只启动1个进程,这样方便客户端之间 传输数据。
$text_worker->count = 1;
$text_worker->onConnect = Test::handle_connection();
$text_worker->onMessage = Test::handle_message();
$text_worker->onClose = Test::handle_close();
Worker::runAll();
class Test{
//当客户端连接上来时分配uid,并保存连接,并通知所有客户端
static public function handle_connection($connection){
global $text_worker,$global_uid;
$connection->uid = ++$global_uid;
}
//当客户端发送消息过来时,转发给所有人
static public function handle_message($connection,$data){
global $text_worker;
foreach($text_worker->connections as $conn){
$conn->send("user[{$connection->uid}] said: $data");
}
}
// 当客户端断开时,广播给所有客户端
static public function handle_close($connection)
{
global $text_worker;
foreach($text_worker->connections as $conn)
{
$conn->send("user[{$connection->uid}] logout");
}
}
}