ThinkPHP 5.1下使用PHPSocket.IO实现websocket通讯
PHPSocket.IO
的官方介绍:
PHPSocket.IO是PHP版本的Socket.IO服务端实现,基于workerman开发,用于替换node.js版本Socket.IO服务端。PHPSocket.IO底层采用websocket协议通讯,如果客户端不支持websocket协议, 则会自动采用http长轮询的方式通讯。PHPSocket.IO实现的Polling通信机制包括Adobe Flash Socket、AJAX长轮询、JSONP轮询等。具体采用哪种机制通讯对于开发者完全透明, 开发者使用的是统一的接口。
下面我们使用ThinkPHP5.1
框架来整合PHPSocket.IO
实现客户端和服务端的通讯。
使用的本地开发环境是PHP5.6.30
+ Apache2.4.25
创建新项目
// 使用ThinkPHP5.1新建项目thinksocket;
$ composer create-project topthink/think thinksocket 5.1.*;
// 进入项目,下载workerman/phpsocket.i包;
$ cd thinksocket
$ composer require workerman/phpsocket.io
这样你的安装工作就做好了。接下来配置需要的模块。
配置模块
结合前阵子的文章:ThinkPHP 5.1自动生成模块及目录、文件
我们编辑好build.php
文件:
return [
// 生成应用公共文件
'__file__' => ['common.php'],
// 定义socketio模块的自动生成
'socketio' => [
'__file__' => ['common.php'],
'__dir__' => ['controller', 'model', 'view'],
'controller' => ['Index', 'Server'],
'model' => [],
'view' => ['index/index'],
],
// 其他更多的模块定义
];
然后运行
$ php think build
Successed
这样就有了socketio模块下面controller
有Index.php
和Server.php
两个控制器和view
下一个index/index
一个视图。
创建服务端
编辑控制器Server.php
为(具体参考注释):
<?php namespace app\socketio\controller; use Workerman\Worker; use PHPSocketIO\SocketIO; use think\Db; class Server{ public function index(){ // 在2021端口创建服务 $io = new SocketIO(2021); $io->on('connection', function($socket)use($io){ $socket->on('chat message', function($msg)use($io){ $io->emit('chat message', $msg); }); // 监听到新的客户端连接即在服务端输出'new connection' echo 'new connection'."\n"; // 并向服务端发送'连接成功' $socket->emit('success', '连接成功'); // 服务端发送消息过来 $socket->on('sendMsg', function($msg)use($io){ // 在服务端输出消息 echo $msg."\n"; // 在收到的消息前面拼接'收到'后向客户端发送回去 $io->emit('sendMsg', '收到"'.$msg.'"'); // 将接受到的消息存储到数据库 $data['msg'] = $msg; Db::table('msg')->insert($data); }); }); // 启动服务 Worker::runAll(); } // 测试数据库链接 public function ceshi(){ $msg = Db::table('msg')->select(); var_dump($msg); } }
为了测试,在数据库新建了一张表msg
用来存储客户端发送过来的消息。
CREATE TABLE `msg` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`msg` varchar(250) DEFAULT NULL,
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4;
这样一个可以返回连接成功消息、接收消息、回复消息、存储消息的简单服务端就做好了。
创建客户端
我们在Index.php
控制器中这样写:
<?php
namespace app\socketio\controller;
use think\Controller;
class Index extends Controller
{
public function index()
{
return view();
}
}
在对应的模版文件view/index/index.html
中代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>测试WebSocket</title>
</head>
<body>
<input type="text" name="" id="msg">
<button id='send'>发送消息</button>
</body>
<script src='https://cdn.bootcss.com/socket.io/2.0.3/socket.io.js'></script>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script>
// 如果服务端不在本机,请把127.0.0.1改成服务端ip
var socket = io('http://127.0.0.1:2021');
// 当连接服务端成功时触发connect默认事件
socket.on('connect', function(){
console.log('connect success');
});
socket.on('success', function(msg){
// 连接后弹出服务端返回的消息'连接成功'
alert(msg);
});
socket.on('sendMsg', function(msg){
// 将服务端返回的消息输出到控制台
console.log(msg);
});
// 向服务端发送消息
$('#send').on('click', function(){
var text = $('#msg').val();
socket.emit('sendMsg', text);
// alert(text);
})
</script>
</html>
到这里,一个具备连接服务端,发送消息,接受并输出消息到控制台的简单websocket
客户端就建好了。
为服务端绑定入口文件
在项目的public
文件夹下新建一个入口文件server.php
并将其绑定到socketio
模块的Server
控制器index
方法;
入口文件server.php
代码:
<?php
// [ 应用入口文件 ]
namespace think;
// 加载基础文件
require __DIR__ . '/../thinkphp/base.php';
// 执行应用并响应(绑定)
Container::get('app')->bind('socketio/Server')->run()->send();
测试通讯
运行服务端
直接运行项目public
目录下的server.php
;
D:\xampp\htdocs\thinksocket\public>php server.php
----------------------- WORKERMAN -----------------------------
Workerman version:3.5.11 PHP version:5.6.30
------------------------ WORKERS -------------------------------
worker listen processes status
PHPSocketIO socketIO://0.0.0.0:2021 1 [ok]

这个输出表示PHPSocketIO
已经成功在2021
端口运行监听中。
我们打开浏览器打开http://localhost/thinksocket/public/index.php/socketio/
页面;
可以看到页面会弹出‘链接成功’,同时可以看到服务端cmd
终端上打印出new connection
,同事浏览器控制台会输出connect success
,代表已经成功与服务端连接上。
测试发送消息
在页面输入框内输入任意信息,服务端cmd
终端将会打印信息,代表服务端收到信息,然后服务端控制台将会输出‘收到’+发送的信息。
至此,我们的测试完成。
温馨提示:对程序修改后需要重新启动服务端才能生效
以上只是简单的利用ThinkPHP5.1
的框架测试PHPSocket.IO
通讯。
源代码地址:https://github.com/hsu1943/thinksocketio
供大家参考。
原文链接: https://beltxman.com/1885.html