👀方案一:将服务端当客户端去链接socket服务,给指定客户端发消息
👀方案二:通过http服务去给指定客户发送消息
#### 根据 `PHPSocket.io`里面提供的方案,这里选择方案二,用http请求去给指定客户端发送消息
😄调用方式(GET触发):前提是用户996跟997都登陆上线了 <a href="http://114.96.100.72:5657/ " style="background-color: rgb(255 82 0); color: #ffffff; border: none; padding: 10px 20px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; transition-duration: 0.4s; cursor: pointer; border-radius: 4px; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);">🚀优先点击上线 </a> 🦄 🦄 🦄 🦄 🦄 🦄 🦄 🦄
*****
<a href="http://114.96.100.72:2121/?type=publish&content=你好,这是服务端消息&to=996" style="background-color: #007bff; color: #ffffff; border: none; padding: 10px 20px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; transition-duration: 0.4s; cursor: pointer; border-radius: 4px; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);">
👦后端给用户996发消息
</a>
<a href="http://114.96.100.72:2121/?type=publish&content=你好,这是服务端消息&to=997" style="background-color: #007bff; color: #ffffff; border: none; padding: 10px 20px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; transition-duration: 0.4s; cursor: pointer; border-radius: 4px; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);">
👧 后端给用户997发消息
</a>
<div style="width:100%;margin-top:10px;padding:20px; height: 180px; background-color: #ffffff; border-radius: 10px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);">
<style>
.styled-link { color: #007bff; text-decoration: none; transition: color 0.3s ease; } .styled-link:hover { color: #ff0000; }
</style>
<span style="color: #007bff; text-decoration: none; transition: color 0.3s ease;" onmouseover="this.style.color = '#ff0000';" onmouseout="this.style.color = '#007bff';">
http://114.96.100.72:2121/?type=publish&content=你好,这是服务端消息&to=996
</span>
<b>链接说明</b>
🦐content:是内容
🐴to:是对应的链接到socket的用户id,这个是用户自定义的。如果放到业务场景里面也可以取数据库的id
🍎114.96.100.72:2121:是我部署的一台测试服务器,后期如果服务器到期了,会换这个地址
</div>
*****
核心代码:
```
// 当$sender_io启动后监听一个http端口,通过这个端口可以给任意uid或者所有uid推送数据
$sender_io->on('workerStart', function(){
// 监听一个http端口
$inner_http_worker = new Worker('http://0.0.0.0:2121');
// 当http客户端发来数据时触发
$inner_http_worker->onMessage = function(TcpConnection $http_connection, Request $request){
global $uidConnectionMap;
$post = $request->post();
$post = $post ? $post : $request->get();
// 推送数据的url格式 type=publish&to=uid&content=xxxx
switch(@$post['type']){
case 'publish':
global $sender_io;
$to = @$post['to'];
$post['content'] = htmlspecialchars(@$post['content']);
// 有指定uid则向uid所在socket组发送数据
if($to){
$sender_io->to($to)->emit('new_msg', $post['content']);
// 否则向所有uid推送数据
}else{
$sender_io->emit('new_msg', @$post['content']);
}
// http接口返回,如果用户离线socket返回fail
if($to && !isset($uidConnectionMap[$to])){
return $http_connection->send('offline');
}else{
return $http_connection->send('ok');
}
}
return $http_connection->send('fail');
};
// 执行监听
$inner_http_worker->listen();
// 一个定时器,定时向所有uid推送当前uid在线数及在线页面数
Timer::add(1, function(){
global $uidConnectionMap, $sender_io, $last_online_count, $last_online_page_count;
$online_count_now = count($uidConnectionMap);
$online_page_count_now = array_sum($uidConnectionMap);
// 只有在客户端在线数变化了才广播,减少不必要的客户端通讯
if($last_online_count != $online_count_now || $last_online_page_count != $online_page_count_now)
{
$sender_io->emit('update_online_count', "当前<b>{$online_count_now}</b>人在线,共打开<b>{$online_page_count_now}</b>个页面");
$last_online_count = $online_count_now;
$last_online_page_count = $online_page_count_now;
}
});
});
```