适用于已经安装好的workerman
没安装和打通的 地址
Worker.php文件
<?php
namespace app\controller\Index;
use app\model\Broadcast;
use app\model\Speech;
use app\model\User;
use think\worker\Server;
use Workerman\Lib\Timer;
class Worker extends Server
{
protected $socket = 'websocket://0.0.0.0:9527';
protected $uidConnections = [];//uid存储
static $id = 0;
static $count = 0;
/**
* 检测心跳
*/
// protected static $heartbeat_time = 1500;
/**
* 收到信息
* @param $connection
* @param $data
*/
public function onMessage($connection, $data)
{
$obj = json_decode($data);
//是否被禁言
$user = User::where('openid', $obj->openid)->where('prohibit_speak', 0)->find();
if (empty($user)) {
$data = '$obj->name'.'||'.'$obj->openid'.'||'.'$obj->text'.'||'. 'self::$count'.'||'.'201';
//针对禁言的用户
$this->sendMessageByUid($this->uidConnections[$connection->uid]->uid,$data);
} else {
$data = '$obj->name'.'||'.'$obj->openid'.'||'.'$obj->text'.'||'. 'self::$count'.'||'.'200';
$this->broadcast($data);
}
}
/**
* 当连接建立时触发的回调函数,应用n秒一次广播
* @param $connection
*/
public function onConnect($connection)
{
self::$count++;
// 判断当前客户端是否已经验证,既是否设置了uid,设置了直接发送消息,未设置第一次为设置uid
if (!isset($connection->uid)) {
$connection->uid = $data;
/* 保存uid到connection的映射,这样可以方便的通过uid查找connection,
* 实现针对特定uid推送数据
* $this->sendMessageByUid($this->uidConnections[$connection->uid]->uid,$data);
*/
$connection->uid = self::$id++;
$this->uidConnections[$connection->uid] = $connection;
$data = '***会员'.'||'.'0'.'||'.'来了'.'||'.self::$count.'||'.'202';
$this->broadcast($data);
}
//定时器,5分钟广播一次
Timer::add(60*5, function () {
$broadcast = Broadcast::where('states',1)->find();//广播的数据
if (!empty($broadcast)){
$broadcast = $broadcast['broadcast_text'];
$data = '管理员'.'||'.'0'.'||'.$broadcast.'||'.self::$count.'||'.'200';
$this->broadcast($data);
}
});
}
/**
* 当连接断开时触发的回调函数
* @param $connection
*/
public function onClose($connection)
{
self::$count--;
if(isset($connection->uid))
{
// 连接断开时删除映射
$data = '***会员'.'||'.'0'.'||'.'退出了||'.self::$count.'||'.'203';
$this->broadcast($data);
unset($this->uidConnections[$connection->uid]);
#关闭连接
$connection->close();
}
}
/**
* 当客户端的连接上发生错误时触发
* @param $connection
* @param $code
* @param $msg
*/
public function onError($connection, $code, $msg)
{
echo "error $code $msg\n";
}
/**
* 每个进程启动
* @param $worker
*/
public function onWorkerStart($worker)
{
}
// 向所有验证的用户推送数据
function broadcast($message)
{
foreach($this->uidConnections as $connection)
{
$connection->send($message);
}
}
// 针对uid推送数据
function sendMessageByUid($uid, $message)
{
if(isset($this->uidConnections[$uid]))
{
$connection = $this->uidConnections[$uid];
$connection->send($message);
return true;
}
return false;
}
}
js部分
getWebsocetData(val) {
// val = String.fromCharCode.apply(null, new Uint8Array(val)).trim() //如果后端返回数据格式是其他的,可能需要转换一下,比如这个,应该是转Unicode编码
console.log(val,'回调函数')
let that = this;
val = val.split('||')
that.participate = parseInt(val[3])//在线人数
if(val[4] === '200'){
let data = {
name:val[0],
openid:val[1],
text:val[2]
}
that.datas = that.datas.concat(data)//追加数组
//that.pageToBottom(that);这是本人自己写的,有新信息自动下拉到最新信息那
}else if(val[4] === '203'){
}else{
uni.showToast({
title: '发送失败...',
icon: 'none',
duration: 2000
})
}
}