文章目录
聊天界面布局
在View/Index目录下创建index.html
html代码
html
<div id="chat">
<div id="nbar">
<div class="pull-left">与牛德胜正在聊天...</div>
<div class="pull-right" id="to_user_status"><span>离线</span></div>
</div>
<div id="chat_content">
<div class="media">
<div class="media-left">
<img class="media-object avatar" src="/Uploads/avatar/4.jpg">
</div>
<div class="media-body">
<h4 class="media-heading">牛德胜</h4>
<p class="chat_msg_left">
对对对 </p>
</div>
</div>
<div class="media_right">
<div class="media-body">
<h4 class="media-heading">黎明</h4>
<p class="chat_msg_right">
顶顶顶顶 </p>
</div>
<div class="media-right">
<img class="media-object avatar" src="/Uploads/avatar/1.jpg">
</div>
</div>
<div class="media">
<div class="media-left">
<img class="media-object avatar" src="/Uploads/avatar/4.jpg">
</div>
<div class="media-body">
<h4 class="media-heading">牛德胜</h4>
<p class="chat_msg_left">
订单 </p>
</div>
</div>
<div class="media_right">
<div class="media-body">
<h4 class="media-heading">黎明</h4>
<p class="chat_msg_right">
对对对 </p>
</div>
<div class="media-right">
<img class="media-object avatar" src="/Uploads/avatar/1.jpg">
</div>
</div>
</div>
<div class="form-inline" style="position: relative;">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon" onclick="emoj()">表情</div>
<input type="text" class="form-control" id="msgcontent">
<div class="input-group-addon" style="cursor: pointer;" onclick="choose_image()">图片</div>
<input type="file" name="file" id="file" accept="image/*" style="display: none" onchange="send_image()">
</div>
</div>
<button type="button" class="btn btn-primary" onclick="send_msg()">发送</button>
</div>
</div>
页面布局实现效果如下。
布局是个简单的事儿,重点就是聊天内容展示,左边是对方,右边是自己。这两个每个单独用一个div包裹起来。有新的聊天信息追加的时候比较方便。直接在最后追加。
创建websocket连接
html
<script>
ws=new WebSocket("ws://127.0.0.1:8282");
ws.onmessage=function (e){
// json数据转换成js对象
var data = eval("("+e.data+")");
var type = data.type || '';
console.log(data)
switch(type){
// Events.php中返回的init类型的消息,将client_id发给后台进行uid绑定
case 'init':
// 利用jquery发起ajax请求,将client_id发给后端进行uid绑定
$.post('/chat.php/Chat/bind', {client_id: data.client_id}, function(data){}, 'json');
break;
default :
alert(e.data);
}
}
</script>
下面这句在页面加载的时候就创建了websocket连接。
ws=new WebSocket("ws://127.0.0.1:8282");
ws.onmessage这个函数是有消息从服务端推送过来的时候就自动接收。
还记得GatewayWorker\Applications\YourApp\Events.php文件里的内容吗,里边的这段代码就是有连接的时候,服务器就会自动回复一条消息,我们将这条消息以json字符串的形式发给客户端。定义了消息的类型init,也就是第一次连接的时候,初始化。
根据服务端返回的消息,将字符串json转为真的json,然后解析里边的数据
js
// json数据转换成js对象
var data = eval("("+e.data+")");
var type = data.type || '';
之后根据返回的数据类型,进行相应的处理。第一次初始化,根据服务端返回的client_id,把当前客户的id和client_id发送给服务端,让服务端把用户id和client_id进行绑定。
js
switch(type){
// Events.php中返回的init类型的消息,将client_id发给后台进行uid绑定
case 'init':
// 利用jquery发起ajax请求,将client_id发给后端进行uid绑定
$.post('/chat.php/Chat/bind', {client_id: data.client_id}, function(data){}, 'json');
break;
default :
alert(e.data);
}
接下来在Controller文件夹下创建ChatController.php,里边添加一个bind方法,来绑定id和client_id
别忘了引用Gateway,这就是之前添加GatewayClient的原因。有了这个客户端,就可以在PHP的框架里直接对Gatewayworker进行操作。
use GatewayClient\Gateway;
js
public function bind(){
$client_id=I('post.client_id');
// 设置GatewayWorker服务的Register服务ip和端口,请根据实际情况改成实际值(ip不能是0.0.0.0)
Gateway::$registerAddress = '127.0.0.1:1238';
// 假设用户已经登录,用户uid和群组id在session中
$uid = $_SESSION['user_id'];
// client_id与uid绑定
Gateway::bindUid($client_id, $uid);
}
到此,就实现了客户端以服务端的连接,并将客户端用户id与client_id进行绑定。
为什么要绑定?
服务端给每个链家创建一个client_id,这个id是一串很长的字符串:7f0000010b5400000006。这种怎么区分谁给谁发送呢。将用户id与client_id绑定后,只要给用户id发送信息,服务端自动找到对应的client_id发送信息。一个用户id可以绑定多个client_id,但是一个client_id只能绑定一个用户id。适用场景如下:
你可以打开多个网页跟同一个人聊天,每打开一个页面,就会创建一个socket连接,就会有一个client_id。都是你一个人聊天,用户的id是同一个。