之前的文章写到了workerman的连接嘛。这次继续之前的,先弄两个页面吧。
大概就是弄了这样的两个页面的哈。类似的静态页面啊,网上都会有的。异曲同工的哈。就是把html文件替换成在应用/view/控制器/方法.html
把网上下载的代码放在这个 方法.html
里面。然后把其他所有的文件夹,图片啊,css,js的文件放在public文件夹下就OK了。然后把路径加工一下,最最最简单的方法就是在所有的链接前面加
“/”.像这样,
好了,继续吧先。
简单说下思路吧。前端连接的时候 可以通过ajax进行绑定user_id和workman为每个用户分配的id。这样就可以实现推送了。贴下我的代码吧。就是简单一个实现。学一学就可以了。实际项目中估计也不会这么用,直接用getwayworker了。
public function onConnect($connection)
{
// 生成一个唯一用户的客户端id
$this->client_id = time().rand(100,999);
// 将生成的client_id赋给当前连接
$connection->client_id = $this->client_id;
// 在当前worker对象中新添属性 保存当前登录的用户的client_id 和 连接对象
// 以便进行推送
$this->worker->clientIdConnections[$connection->client_id] = $connection;
// 将生成的client_id发送给客户端
$json = [
'type' => 'bind',
'from' => 'worker',
'to' => $connection->client_id,
'content' => $this->client_id
];
$connection->send(json_encode($json,true));
}
这个是前端的代码。给每个用户的user_id和workerman为每个用户分配的id进行绑定 ,这样就可以实现指定用户推送了。
ws = new WebSocket("ws://www.chat.com:2346");
ws.onopen = function() {
};
ws.onmessage = function(e) {
var result = JSON.parse(e.data);
if (result.type == 'bind') {
// 请求mvc框架绑定数据
$.get("<{:url('index/Index/bind')}>"+"?uid="+<{$uid}>+"&client_id="+result.content,function(e){
if (!e || e.code != 200) {
alert("连接失败,请重新登录");
window.location.href = "<{:url('index/Login/index')}>";
}
});
} else if (result.type == 'say') {
console.log(result);
}
};
推送:
public function onMessage($connection, $data)
{
$data = json_decode($data,true);
if ($data["type"] == "say") {
$result["type"] = "say";
$result["from"] = $data["from"];
$result["to"] = $data["to"];
$result["content"] = $data["content"];
// dump($this->worker);
$this->worker->clientIdConnections[$data["to"]]->send(json_encode($result,true));
}
}
ajax绑定用户:
public function bind(){
// 绑定用户和客户端
$get = Request::get();
$result["code"] = 200;
// 检查参数
if (empty($get['uid']) || empty($get['client_id'])) {
$result["message"] = "参数错误";
$result["data"] = [];
return json($result);
}
// 绑定用户session和client_id
$connectionInfo = [];
if (Session::has("connectionInfo")) {
$connectionInfo = Session::get("connectionInfo");
}
$connectionInfo[$get["uid"]] = $get["client_id"];
Session::set("connectionInfo",$connectionInfo);
$result["code"] = 200;
$result["message"] = '成功';
$result["data"] = $connectionInfo;
return json($result);
}
整体的效果也没时间弄了。到最后数据是正确的 剩下就是前端的效果了。整体的思路就是将数据库的user_id和workerman为每个用户分配的id进行绑定。绑定后就可以实现指定用户推送了。
到最后也就是一个半成品吧。
{ “from” : 1615112847935 , “to” : 1615112847955 , “content” : “来了老弟” ,
“type” : “say” }
我的数据格式是这样子的,数据格式嘛,怎么来都可以。
前端:
<html>
<head>
<meta charset="utf-8">
<title>双子稚心丶Amor</title>
<link href="/css/style.css" rel="stylesheet" type="text/css">
<script src="/js/jquery.js"></script>
<script src="/js/index.js"></script>
<script src="/js/superslide.2.1.js"></script>
<script src="/js/nicescroll.js"></script>
<script>
ws = new WebSocket("ws://www.chat.com:2346");
ws.onopen = function() {
// console.log("连接成功");
// JSON.stringify(data);
// JSON.parse(data);
// data = { "from" : 1615112847935 , "to" : 1615112847955 , "content" : "来了老弟" , "type" : "say" };
// console.log(JSON.stringify(data));
// ws.send(JSON.stringify(data));
};
ws.onmessage = function(e) {
var result = JSON.parse(e.data);
if (result.type == 'bind') {
// 请求mvc框架绑定数据
$.get("<{:url('index/Index/bind')}>"+"?uid="+<{$uid}>+"&client_id="+result.content,function(e){
if (!e || e.code != 200) {
alert("连接失败,请重新登录");
window.location.href = "<{:url('index/Login/index')}>";
}
});
} else if (result.type == 'say') {
console.log(result);
}
};
</script>
</head>
<body style="background-image: url(/images/snow.jpg);background-size: cover;">
<div class="win-bg"><img src="/images/win-bg.png"></div>
<div class="qq" style="display: block;right: 200px;">
<div class="qq-top">
<div class="qq-top-icon">
<i><img src="/images/qq-top.png"></i>
<span class="qq-top-02 close"><img src="/images/qq-top-02.png"></span>
<span class="qq-top-01 min"><img src="/images/qq-top-01.png"></span>
</div>
<div class="qq-top-name">
<span><{$memberInfo["uname"]}></span>></span>
<dl><dd><img src="/images/zai.png"></dd><dt><img src="/images/lv.png"></dt><dt><img src="/images/svip.png"></dt></dl>
</div>
<div class="qq-top-shuo"><input type="text" value="这两天空间被各种婚礼刷屏了"></div>
<div class="qq-top-menu">
<ul>
<li></li><li></li><li></li><li></li>
</ul>
<span class="qq-top-001"></span>
<span class="qq-top-002"></span>
</div>
<div class="qq-serch">搜索:联系人、讨论组、群、企业</div>
</div>
<div class="qq-xuan">
<ul>
<li class="qq-xuan-li"><span></span><i></i></li>
<li><span></span><i></i></li>
<li><span></span><i></i></li>
<li><span></span><i></i></li>
</ul>
</div>
<div class="qq-hui">
<ul>
{foreach $friendInfo as $key => $item}
<li>
<div class="qq-hui-img"><img src="<{$item['head_img']}>"><i></i></div>
<div class="qq-hui-name"><span><{$item["uname"]}></i></span><i>16:30</i></div>
<div class="qq-hui-txt" title="">下次我们去公园拍摄吧~[图片]</div>
</li>
{/foreach}
</ul>
</div>
<div class="qq-bot">
<div class="qq-menu">
<ul>
<li><img src="/images/bot-menu/01.png"></li>
<li><img src="/images/bot-menu/02.png"></li>
<li><img src="/images/bot-menu/03.png"></li>
<li><img src="/images/bot-menu/04.png"></li>
<li><img src="/images/bot-menu/05.png"></li>
<li><img src="/images/bot-menu/06.png"></li>
<li><img src="/images/bot-menu/07.png"></li>
<li><img src="/images/bot-menu/08.png"></li>
<li><img src="/images/bot-menu/09.png"></li>
<li><img src="/images/bot-menu/10.png"></li>
</ul>
</div>
<div class="qq-bou-she">
<ul>
<li><img src="/images/bot-menu/11.png"></li>
<li><img src="/images/bot-menu/12.png"></li>
<li><img src="/images/bot-menu/13.png"></li>
<li><img src="/images/bot-menu/14.png"></li>
<li><img src="/images/bot-menu/15.png"></li>
<li><img src="/images/bot-menu/16.png"><span>查找</span></li>
<li><img src="/images/bot-menu/05.png"><span>应用宝</span></li>
</ul>
</div>
</div>
</div>
<div class="qq-chat">
<div class="qq-chat-win">
<ul>
<li class="she"></li><li class="min"></li><li class="max"></li><li class="close"></li>
</ul>
</div>
<div class="qq-chat-top">
<div class="qq-chat-tops">
<div class="qq-chat-t-head"><img src=""></div>
<div class="qq-chat-t-name"></div>
<div class="qq-chat-t-shuo">站在别人的雨季,淋湿自己空弹一出戏.....</div>
</div>
<div class="qq-chat-menu">
<ul>
<li><span><img src="/images/chat/icon-01.png"></span></li>
<li><span><img src="/images/chat/icon-02.png"></span></li>
<li><span><img src="/images/chat/icon-03.png"></span><i></i></li>
<li><span><img src="/images/chat/icon-04.png"></span><i></i></li>
<li><span><img src="/images/chat/icon-05.png"></span><i></i></li>
<li><span><img src="/images/chat/icon-06.png"></span></li>
<li><span><img src="/images/chat/icon-07.png"></span><i></i></li>
</ul>
</div>
</div>
<div class="qq-chat-bot">
<div class="qq-chat-txt">
<ul>
<li>
<div class="qq-chat-you blue"><span></span><i></i></div>
<div class="qq-chat-ner">在么?找你有点事</div>
</li>
</ul>
</div>
<div class="qq-chat-text">
<ul>
<li><span><img src="/images/chat/menu-01.png"></span></li>
<li><span><img src="/images/chat/menu-02.png"></span></li>
<li><span><img src="/images/chat/menu-03.png"></span></li>
<li><span><img src="/images/chat/menu-04.png"></span></li>
<li><span><img src="/images/chat/menu-05.png"></span><i></i></li>
<li><span><img src="/images/chat/menu-06.png"></span></li>
<li><span><img src="/images/chat/menu-07.png"></span><i></i></li>
<li><span><img src="/images/chat/menu-08.png"></span></li>
<li><span><img src="/images/chat/menu-09.png"></span><i></i></li>
<li class="fr" style="margin-right:5px;"><span><img src="/images/chat/menu-10.png"></span><p>消息记录</p><i></i></li>
</ul>
<textarea id="qq-chat-text"></textarea>
<div class="qq-chat-but">
<span class="fasong">发送(S)</span>
<span class="close-chat">关闭(C)</span>
</div>
</div>
</div>
</div>
</body>
</html>
控制器:
<?php
namespace app\index\controller;
use think\facade\View;
use app\BaseController;
use think\worker\Server;
use think\facade\Session;
use app\index\model\Memberfriend;
use app\index\model\Member;
use think\facade\Request;
class Index extends BaseController{
public function index(){
// 检查是否登录
if (!Session::has("user_id")) {
redirect(url("index/Login/index"))->send();
}
$user_id = Session::get("user_id");
$this->uid = $user_id;
trace("index");
$memberInfo = Member::find($user_id);
// 获取好友列表
$friend_rt = Memberfriend::getMembers($user_id)->toArray();
$friend = explode(",",$friend_rt['user_friend']);
// 获取好友列表信息
$friendInfo_rt = Member::getMemberInfo([["id","in",$friend]])->toArray();
foreach ($friendInfo_rt as $key => $value) {
$friendInfo[$value['id']] = $value;
}
// 渲染到页面
View::assign([
'friendInfo' => $friendInfo,
'memberInfo' => $memberInfo,
'uid' => $user_id
]);
return View::fetch();
}
public function bind(){
// 绑定用户和客户端
$get = Request::get();
$result["code"] = 200;
// 检查参数
if (empty($get['uid']) || empty($get['client_id'])) {
$result["message"] = "参数错误";
$result["data"] = [];
return json($result);
}
// 绑定用户session和client_id
$connectionInfo = [];
if (Session::has("connectionInfo")) {
$connectionInfo = Session::get("connectionInfo");
}
$connectionInfo[$get["uid"]] = $get["client_id"];
Session::set("connectionInfo",$connectionInfo);
$result["code"] = 200;
$result["message"] = '成功';
$result["data"] = $connectionInfo;
return json($result);
}
}
worker类:
<?php
namespace app\index\controller;
use think\facade\View;
use think\worker\Server;
use think\facade\Session;
use GatewayClient\Gateway;
// require_once '../vendor/autoload.php';
// use app\index\model\Memberfriend;
// use app\index\model\Member;
class Worker extends Server{
// json消息格式{
// type : say--发送的消息 bind--用户连接绑定client_id
// from : 谁发的
// to : 给谁发的
// content : '发的内容'
// }
protected $socket = 'websocket://www.chat.com:2346';
protected $client_id;
public function onMessage($connection, $data)
{
$data = json_decode($data,true);
if ($data["type"] == "say") {
$result["type"] = "say";
$result["from"] = $data["from"];
$result["to"] = $data["to"];
$result["content"] = $data["content"];
// dump($this->worker);
$this->worker->clientIdConnections[$data["to"]]->send(json_encode($result,true));
}
// $json = [
// 'type' => 'say',
// 'from' => '1615112847955',
// 'to' => $connection->client_id,
// 'content' => $data["content"]
// ];
// $connection->send(json_encode($json,true));
}
/**
* 当连接建立时触发的回调函数
* @param $connection
*/
public function onConnect($connection)
{
// 生成一个唯一用户的客户端id
$this->client_id = time().rand(100,999);
// 将生成的client_id赋给当前连接
$connection->client_id = $this->client_id;
// 在当前worker对象中新添属性 保存当前登录的用户的client_id 和 连接对象
// 以便进行推送
$this->worker->clientIdConnections[$connection->client_id] = $connection;
// 将生成的client_id发送给客户端
$json = [
'type' => 'bind',
'from' => 'worker',
'to' => $connection->client_id,
'content' => $this->client_id
];
$connection->send(json_encode($json,true));
}
/**
* 当连接断开时触发的回调函数
* @param $connection
*/
public function onClose($connection)
{
}
/**
* 当客户端的连接上发生错误时触发
* @param $connection
* @param $code
* @param $msg
*/
public function onError($connection, $code, $msg)
{
echo "error $code $msg\n";
}
/**
* 每个进程启动
* @param $worker
*/
public function onWorkerStart($worker)
{
}
}
这是代码:https://gitee.com/zqy-904915452/tp6-workerman-chat