标题: [精]简易多用户websocket服务端
时间: 2019-05-09
<?php
namespace app\socket\controller;
use think\worker\Server;
class Index extends Server
{
protected $socket = 'websocket://127.0.0.11:8001';
/**
* 收到信息
* @param $connection
* @param $data
*/
public function onMessage($connection, $data)
{
if(!json_decode($data,true))
{
return ;
}
$client=json_decode($data,true);
if(!isset($client['msg']))
{
return;
}
$param=[
'type'=>'speak',
'speaker_uid'=>$connection->uid,
'speaker_msg'=>$client['msg']
];
//除了那个新来的不通知
$this->radio($this->AopReturn($param),$connection->uid);
echo '收到客户端UID'.$connection->uid.'->'.$data."\n";
}
/**
* 当连接建立时触发的回调函数
* @param $connection
*/
public function onConnect($connection)
{
$connection->uid =$this->uin++; //给于这个用户一个唯一的UID
$param=[
'type'=>'join',
'new_uid'=>$connection->uid
];
//除了那个新来的不通知
$this->radio($this->AopReturn($param),$connection->uid);
echo '客户端连接UID:'.$connection->uid."\n";
}
/**
* 当连接断开时触发的回调函数
* @param $connection
*/
public function onClose($connection)
{
$param=[
'type'=>'exit',
'uid'=>$connection->uid
];
//除了那个离线的的不通知
$this->radio($this->AopReturn($param),$connection->uid);
echo '客户端断开UID:'.$connection->uid."\n";
}
public function AopReturn($array)
{
return json_encode($array);
}
/**
* @param $msg广播
*/
public function radio($msg,$unset_uid=0)
{
foreach ($this->worker->connections as $each)
{
if($each->uid==$unset_uid)
{
continue;
}
$each->send($msg);
}
}
/**
* 当客户端的连接上发生错误时触发
* @param $connection
* @param $code
* @param $msg
*/
public function onError($connection, $code, $msg)
{
echo "error $code $msg\n";
}
/**
* 每个进程启动
* @param $worker
*/
public function onWorkerStart($worker)
{
echo '进程启动>>>>>>>>>>>>>>>>>>>>>>>>>'."\n";
return ;
echo '进程启动'.json_encode($worker)."\n";
}
}
<html><head>
<meta charset="utf-8">
<title>设置我的资料</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
<script src="/static/js/jq.js"></script>
<link rel="stylesheet" href="/static/layuiadmin/layui/css/layui.css" media="all">
<link rel="stylesheet" href="/static/layuiadmin/style/admin.css" media="all">
<script src="/static/layuiadmin/layui/layui.js"></script>
</head>
<body layadmin-themealias="default">
<div class="layui-container">
<h1 align="center">在线聊天</h1>
<div style="min-height: 60%" class="chatdiv"></div>
<div align="center">
<textarea name="msg" id="msg" cols="30" rows="10">这里写信息</textarea><br>
<button class="layui-btn layui-btn-primary" id="send">发信消息</button>
</div>
</div>
<script>
websocket=function(){
this.ws;
this.init=function () {
this.wsConnect();//连接请求动作发送
this.wsConnectSuccess();//成功连接到服务器
}
/**
* 连接请求动作发送
*/
this.wsConnect=function ()
{
console.log('本地:正在尝试连接');
this.ws = new WebSocket("ws://127.0.0.11:8001");
}
/**
* 成功连接到服务器
*/
this.wsConnectSuccess=function()
{
this.ws.onopen = function(event) {
console.log('本地:连接远程服务器成功');
this.onMessage();//来消息监听
this.sendMessage();//发送消息监听
this.sendBtnStatus();//按钮监听
}.bind(this);
}
this.onMessage=function () {
this.ws.onmessage = function(event)
{
this.onMessageEvent(event.data);
}.bind(this)
}
this.onMessageEvent=function (string)
{
console.log("服务器:主动推送->"+string);
data=eval('('+ string +')');
//data=JSON.parse(string);
if(data.type=='speak')
{
$('.chatdiv').append(data.speaker_uid+"说:"+data.speaker_msg+"<br>");
}
if(data.type=='join')
{
$('.chatdiv').append("新用户ID:"+data.new_uid+"加入了聊天室<br>");
}
if(data.type=='exit')
{
$('.chatdiv').append("用户ID:"+data.uid+"离线<br>");
}
}
/**
* 按钮发送
*/
this.sendMessage=function()
{
$('#send').click(function (event) {
var sendmsg={'type':'speak',"msg":$('#msg').val()};
this.ws.send(JSON.stringify(sendmsg));//
console.log("本地:数据发送->"+sendmsg);
$('.chatdiv').append(+"我说:"+$('#msg').val()+"<br>");//同时
}.bind(this));
}
/**
*
* @returns {string}
*/
this.wsStatus=function ()
{
status = ['未连接','连接成功,可通讯','正在关闭','连接已关闭或无法打开'];
if(this.ws.readyState==1){
return true;
}
return false;
//return status[this.ws.readyState]+'->code:'+ws.readyState;
}
/**
* 按钮状态
*/
this.sendBtnStatus=function ()
{
if(this.wsStatus()){
$('#send').html('发送信息');
$('#send').removeClass('layui-btn-primary');
}else{
$('#send').html('已经离线');
$('#send').addClass('layui-btn-primary');
}
}
}
$(document).ready(function () {
var conn=new websocket();
conn.init();
setInterval(function (){
conn.sendBtnStatus()
},1000);
});
</script>
<script>
</script>
</body>
</html>
『回复列表(6|隐藏机器人聊天)』
/**
* 每个进程启动
* @param $worker
*/
public function onWorkerStart($worker)
{
echo '进程启动>>>>>>>>>>>>>>>>>>>>>>>>>'."\n";
Timer::add(0.1, array($this, 'radioInterval'), null, true);
return;
}
/**
* 定时任务回调函数,比如用来定时广播
*/
public function radioInterval()
{
$msg='北京时间:'.date("Y-m-d H:i:s");
echo '定时广播发送:'.$msg."\n";
$this->radio($this->AopReturn(['type'=>'radio','msg'=>$msg]));
}