来源: thinkphp3.2+workerman(GatewayWorker)+ Layim做即时通讯_菜鸟的博客-CSDN博客
此博客参考https://fly.layui.com/jie/12624/
一,程序实现的逻辑:
后端还是和以前一样,传值给前端。
前端与GatewayWorker建立连接获取特定的连接id
(这样前端就有用户id和连接id)
3.前端通过ajax方法发送用户id和链接id给后端,后端进行绑定
4.监控前端发送消息,发送人id,当触发该事件,传到后端,后端根据用户id值,发送给特定的人
5.监控前端接收消息,当有新消息过来就在页面执行相应的代码
二,环境的搭建
1,下载GatewayWorker
(地址:http://www.workerman.net/download/GatewayWorker-for-win.zip)
2,修改Applications/YourApp/目录下的start_geteway.php 24行左右 修改为$gateway = new Gateway(“websocket://0.0.0.0:8282″);(端口号和前端保持一致)
3,下载workerman的GatewayClient(https://github.com/walkor/GatewayClient);
4,将下载好的Gateway重命名为Gateway.class.php并修改命名空间为namespace Org\Util;
将前面重命名Gateway.class.php复制到thinkphp/library/org/util/目录下
双击启动GatewayWorker根目录下的start_for_win.bat()
如果出现下面:
说明启动成功
如果没有启动成功将有以下解决方法
将php设置为全局环境变量(网上有很多方法)测试是否成功在命令行执行php –v,如果提示“php不是内部或外部命令“之类的就说明没有设置好
如果有下图之类的提示
上图那样有三个问题
php_mcrypt.dll – 找不到指定的模块。
php_pdo.dll – 找不到指定的模块。
proc_open() has been disabled for security reasons.
找不到指定模块:解决方法打开php.ini文件,查找模块名(比如上图php_pdo.dll);找到在这句前面加上“;”。注释掉即可
has been disabled for security reasons.解决方法:就是把这个方法的禁止打开,也是在php.ini文件修改;找到这个方法,直接删掉即可
三,代码部分
后端部分
因为该篇主要讲即时通讯的实现,所以用户信息获取那部逻辑就不做展示。
后端绑定和发送信息
后端接收前端数据的时候,还做了把数据存入数据库的处理,这样就可以实现数据的持久化
前端部分
引入文件
<script src=”__PUBLIC__/JQuery/2.0.0/JQuery.js”></script>
<link rel=”stylesheet” href=”__PUBLIC__/layim/css/layui.mobile.css”>
<script src=”__PUBLIC__/layim/layui.js”></script>
自己信息的初始化
layui.use(‘mobile’, function(layim){
var mobile = layui.mobile
,layim = mobile.layim;
layim.config({
init: {
mine: {
“username”: “{$user.name}” //我的昵称
,”id”: “user{$user.id}” //我的ID
,type: ‘kh’//类型
,”avatar”: “{$user.img}” //我的头像
}
} , chatTitleColor:”#fff”,
chatLog: ‘/chat/log/’
});
(3)创建客服信息
layim.chat({
id: “kf{$kf.id}”
,name: ‘客服{$kf.id}’
,type: ‘kefu’ //friend、group等字符,如果是group,则创建的是群聊
,avatar: ‘/luntan/{$kf.img}’
});
(4)建立连接
var socket = new WebSocket(‘ws://localhost:8282’);//服务器改成ip地址加端口号
连接方法
第一次连接,会收到两次信息,接收后端传来数据也是在这里处理
我们可以在onmessage方法里面进行处理,取出连接值,再传给后端,这样就绑定好了
除了是登录事件,登出事件,就是后端正常我们自己发送的数据了
我们把接收到的值,再进行展示,这样就可以实现我们需要的效果了。
//连接成功时触发
socket.onopen = function(e){
//这里可以写一些提示语
}
//监听收到的消息
socket.onmessage = function(e){
var data = e.data
// console.log(e);
data=data.replace(‘\r\n’,”);//删除换行符
var arr=data.split(” “);
if(arr[0]==”Hello”){
var client_id=arr[1].trim();
//绑定client_id
$.ajax({type: “POST”, url: “{:U(‘Workerman/bind’)}”, data: {
‘uid’:”user{$user[‘id’]}”,
‘client_id’: client_id}, dataType: ‘json’, success: function (res) {
console.log(res);
}});
}else if(arr[1]!=”login”&&arr[1]!=”logout”){
//接收服务器信息
data=JSON.parse(data);
if(data[‘sendid’]==”kf{$kf.id}”){
$(“#link”).html(“可点击进行评价”);
//console.log(data[‘sendname’]);
var obj = {};
obj = {
username:data[‘sendname’]
,avatar: data[‘img’]
,id: ‘kf1’
,type:”kefu”
,content: data[‘content’]
}
layim.getMessage(obj);
}
}
(5)监听用户发送信息
layim.on(‘sendMessage’, function(data){
console.log(data);
var sendid=data.mine.id;
var sendtype=”kh”;
var sendname=data.mine.username;
var sendimg=data.mine.avatar;
var contents=data.mine.content;
var toid=data.to.id;
var toname=data.to.name;
var totype=data.to.type;
var toimg=data.to.avatar;
var talkid=data.mine.id+”|”+data.to.id;
var talktip=data.mine.username+”|”+data.to.name;
$.ajax({
type: “POST”,
url: “{:U(‘User/getcontents’)}”,
data: {
‘sendid’:sendid,
‘sendname’: sendname,
‘sendtype’:sendtype,
‘sendimg’:sendimg,
‘contents’:contents,
‘toid’:toid,
‘toname’:toname,
‘totype’:totype,
‘toimg’:toimg,
‘talkid’:talkid,
‘talktip’:talktip,
},
dataType: ‘json’,
success: function (res) {
console.log(res);
}
})
至此即时通讯的修改就出来
四,数据的持久化,跨设备储存
把聊天记录根据自己的需求存入数据库
单用户进入聊天界面时,根据是谁与谁的聊天,读取相应数据,然后前端得到数据再进行展示。
注意layim聊天记录的要求时间戳是精确到毫秒的
(1),php获取当前毫秒的方法
public function getMillisecond() {
$time = explode (” “, microtime () );
$time = $time [1] . ($time [0] * 1000);
$time2 = explode ( “.”, $time );
$time = $time2 [0];
return $time;
}
(2),前端初始化数据
localStorage.clear();
(3),前端获取数据,并展示
$.ajax({type: “POST”, url: “{:U(‘User/getmsg’)}”, data: {
‘uid’:”user{$user[‘id’]}”,’kid’:”kf{$kf.id}”},
dataType: ‘json’, success: function (res) {
if(res.stu==1){
$(“#link”).html(“获取历史记录成功”);
var msg=res.msg;
// console.log(msg)
for ($i=0;$i<msg.length;$i++){
var isme=false;
if(“user{$user[‘id’]}”==msg[$i].sendid){
isme=true;
}
var obj = {};
obj = {
username:msg[$i].sendname//消息来源用户名
,avatar: msg[$i].sendimg //消息来源用户头像
,id: msg[$i].sendid//消息的来源ID(如果是私聊,则是用户id,如果是群聊,则是群组id)
,type:msg[$i].totype //聊天窗口来源类型,从发送消息传递的to里面获取
,content: msg[$i].contents //消息内容
,mine: isme
,timestamp: parseInt(msg[$i].time) //服务端时间戳毫秒数。注意:如果你返回的是标准的 unix 时间戳,记得要 *1000
}
layim.getMessage(obj);
}
}
}})
这样数据的持久化算是实现了
不过这里还有一个小bug,当执行layim.getMessage()如果是对方数据的时候就有声音提示(也就是上面isme变量为false的时候),所以一打开这个页面就有声音提示,这个是默认打开的,因此我们要把他关闭了
在layim.config里面最后加上“,voice: false“
然后我们自己写收到实时信息的时候发送提示音
Js发送语音提示方法
function playSound() {
var borswer = window.navigator.userAgent.toLowerCase();
if ( borswer.indexOf( “ie” ) >= 0 )
{
//IE内核浏览器
var strEmbed = ‘<embed name=”embedPlay” src=”/Public/layim/css/modules/layim/voice/default.wav” autostart=”true” hidden=”true” loop=”false”></embed>’;
if ( $( “body” ).find( “embed” ).length <= 0 )
$( “body” ).append( strEmbed );
var embed = document.embedPlay;
embed.volume = 100;
} else
{
//非IE内核浏览器
var strAudio = “<audio id=’audioPlay’ src=’/Public/layim/css/modules/layim/voice/default.wav’ hidden=’true’>”;
if ( $( “body” ).find( “audio” ).length <= 0 )
$( “body” ).append( strAudio );
var audio = document.getElementById( “audioPlay” );
//浏览器支持 audion
audio.play();
}
然后再自己需要提示音的时候调用这个方法即可
效果图
最后提示:
如果在服务器搭建的时候记得打开你程序设定的端口的防火墙
命令行窗口不能关闭
以上都是在windows系统搭建的 ,linux搭建这种websocket环境,网上也有很方法
Layim如何修改默认展示的聊天记录的条数
因为layim默认展示20条聊天记录,多的话,以前的记录会被折叠
可以修改lay\modules\mobile.js文件 查找“c=20”后面的条数修改为你需要展示的条数,然后清除浏览器缓存即可(此方法适用于引入moblie的手机版js,pc端可去试试其他文件)
如若有误或者有其他问题请与我交流:2359582968(微信qq同号)
————————————————
版权声明:本文为CSDN博主「一个菜鸡路上不肯回头的人」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_38211838/article/details/82020708