- 首先要去阿里云/腾讯云申请免费的ssl证书
- 配置网站参考基于 https://www.kancloud.cn/bishengzhu/twword/2056626
- 在根目录新增启动文件server.php
<?php
define('app_path', __dir__ . '/application/');
define('bind_module','push/worker');
// 加载框架引导文件
require __dir__ . '/thinkphp/start.php';`
- 新建application/socketio/controller/server.php
<?php
namespace app\socketio\controller;
use workerman\worker;
use workerman\connection\tcpconnection;
use app\admin\model\chatmessage;
use phpsocketio\socketio;
use workerman\redis\client;
//聊天专用workerman
class server
{
public function index()
{
//证书最好是申请的证书
$context = array(
// 更多ssl选项请参考手册 http://php.net/manual/zh/context.ssl.php
'ssl' => array(
// 请使用绝对路径
'local_cert' => 'xxxx.pem', // 也可以是crt文件
'local_pk' => 'xxxx.key',// 也可以是crt文件
'verify_peer' => false,
// 'allow_self_signed' => true, //如果是自签名证书需要开启此选项
)
);
// 这里设置的是websocket协议(端口任意,但是需要保证没被其它程序占用)
$worker = new worker('websocket://0.0.0.0:3120', $context);
// 设置transport开启ssl,websocket+ssl即wss
$worker->transport = 'ssl';
// 启动1个进程对外提供服务
$worker->count = 1;
// 当收到客户端发来的数据后返回hello $data给客户端
// $worker->onmessage = function(tcpconnection $connection, $data){
// global $worker;
// //推送给发送人新消息
// $connection = $worker->data;
// $connection->send('sss---'.$data);
// };
// 新增加一个属性,用来保存uid到connection的映射
$worker->uidconnections = array();
// 当有客户端发来消息时执行的回调函数
$worker->onmessage = function($connection, $data)
{
global $worker;
if(!isset($connection->uid)){
$connection->uid = $data;
$worker->uidconnections[$connection->uid] = $connection;
}else{
foreach($worker->uidconnections as $k=>$connection){
if($k == $data){
$connection->send('你好呀');
}
}
}
};
// 当有客户端连接断开时
$worker->onclose = function($connection)
{
global $worker;
if(isset($connection->uid))
{
// 连接断开时删除映射
unset($worker->uidconnections[$connection->uid]);
}
};
//运行worker
worker::runall();
}
}
-
运行停止指令 需在根目录下执行
守护进程开启: php server.php start -d (后台退出依旧在运行)
开启 : php server.php start (调试模式运行)
关闭: php server.php stop
重启: php server.php restart
查看状态: php server.php status -
前端代码
// 进入这个页面的时候创建websocket连接【整个页面随时使用】
connectsocketinit() {
// 创建一个this.sockettask对象【发送、接收、关闭socket都由这个对象操作】
this.sockettask = uni.connectsocket({
// 【非常重要】必须确保你的服务器是成功的,如果是手机测试千万别使用ws://127.0.0.1:9099【特别容易犯的错误】
url: 'wss://xxxxx:3120/wss',
success(data) {
console.log("websocket连接成功");
},
});
// 消息的发送和接收必须在正常连接打开中,才能发送或接收【否则会失败】
this.sockettask.onopen((res) => {
var that = this;
console.log("websocket连接正常打开中...!");
this.is_open_socket = true;
// 注:只有连接正常打开中 ,才能正常成功发送消息
this.sockettask.send({
data: that.userinfo.id+that.sort,
async success() {
console.log("消息发送成功");
},
});
// 注:只有连接正常打开中 ,才能正常收到消息
this.sockettask.onmessage((res) => {
that.getmessage();
console.log("收到服务器内容:" + res.data);
});
})
// 这里仅是事件监听【如果socket关闭了会执行】
this.sockettask.onclose(() => {
console.log("已经被关闭了");
var that = this;
if (that.is_open_socket == true) {
settimeout(function() {
that.reconnect()
}, 5000);
}
})
},
// 关闭websocket【离开这个页面的时候执行关闭】
closesocket() {
var that = this;
that.is_open_socket = false;
this.sockettask.close({
success(res) {
console.log("关闭成功", res)
},
fail(err) {
that.is_open_socket = true;
console.log("关闭失败", err)
}
})
},
//进入重新连接
reconnect() {
console.log('进入断线重连');
// this.sockettask.close();
this.sockettask = null;
this.connectsocketinit()
},
// //发送消息
sendsocketmessage(msg) {
return new promise((reslove, reject) => {
this.sockettask.send({
data: msg,
success(res) {
console.log('发送成功')
reslove(res)
},
fail(res) {
console.log('发送失败')
console.log(res)
reject(res)
}
});
})
},
- 页面关闭时必须关闭链接
// 关闭websocket【必须在实例销毁之前关闭,否则会是underfined错误】
this.closesocket();
发表评论