tp5结合workerman+gateway实现简单的IM

为何突然想到要实现IM,其实也是源于自己正在弄客服系统,所以想到用socket,而php里最为成熟并且多人使用的想必就是workerman了,而tp5也实现了结合workerman的包了点击打开链接

而我也是从这篇文章中借鉴修改的点击打开链接 可以看看这篇,写的很详细,我的引入是使用原生引入

composer require workerman/workerman
composer require workerman/gateway-worker
在借鉴的过程中,由于自己的细节处理不好导致一个小错误影响了自己大半天时间排查
$gateway = new Gateway('websocket://0.0.0.0:8282');
        $gateway->name = 'WebIMGateway';
        $gateway->count = 4;
        $gateway->lanIp = '127.0.0.1';
        $gateway->startPort = 2900;

就是在这里,8282端口前面的这个冒号,由于我是在linux虚拟机里开发,没注意到

在例子上有些地方自己删了有些地方自己修改过,毕竟每个人对功能的需求不一样,例子中没有加入心跳检测,但是workerman的介绍中,说明了心跳检测的重要性,那么我们有必要加入,很简单的两行代码

//心跳数据
        $gateway->pingData = '{"type":"ping"}';
        //心跳间隔
        $gateway->pingInterval = 30;

前端页面就是很简单的实现socket功能,当然我的虚拟机设置了虚拟域名

<script>
           var ws = new WebSocket("ws://adifree.ctapp.com:8282");
        	ws.onopen = function() {
        		var login_data = '{"type":"init","id":"2","username":"测试大神","avatar":"/uploads/20170907/609063cd7a33ad6170d06640765b8c99.png","sign":"yybsafhajshf"}';
        	    ws.send(login_data);
        	    console.log(login_data);
        		console.log('socket握手成功');
        	}
        	ws.onmessage = function(res){
        		console.log(res.data);
        		var data = eval("("+res.data+")");
        	    switch(data['message_type']){
        	        // 服务端ping客户端
        	        case 'ping':
        	        	ws.send('{"type":"ping"}');
        	            break;
        	        // 登录 更新用户列表
        	        case 'init':
        	            //console.log(data['id']+"登录成功");
        	            break;
        	         // 检测聊天数据
        	        case 'chatMessage':
        	        	var dd = new Date(data.data.timestamp);
        	        	var date = formatDate(dd);
        	        	var chat_msg = '-->'+date+":"+data.data.content+"\n";
        	        	var old_msg = $('#chat-content').val();
        				 $('#chat-content').val(old_msg+chat_msg);
        				 $('input[name=msg]').val('');
        				console.log(date);
        	        	console.log(dd);
        	        	console.log(data.data);
        	            break;
        	        // 离线消息推送
        	        case 'logMessage':
        	            setTimeout(function(){}, 1000);
        	            break;
        	        // 用户退出 更新用户列表
        	        case 'logout':
        	        	break;
        	    }
        	}
        	
        	//发送消息
        	$('#sendMsg').on('click',function(){
        		var content = $('input[name=msg]').val();
        		var res = new Array();
        		res['mine'] = {
        				avatar:"/uploads/20170907/609063cd7a33ad6170d06640765b8c99.png",
        				content:content,
        				id:2,
        				mine:true,
        				username:"测试大神",
        		};
        		res['to'] = {
        				avatar:"abc.png",
        				name:"kefu1",
        				id:1,
        				sign:"测试测试测试",
        				type:"friend",
        				username:"kefu1",
        		};
        		var mine = JSON.stringify(res.mine);
        		var to = JSON.stringify(res.to);
        		var chat_data = '{"type":"chatMessage","data":{"mine":'+mine+', "to":'+to+'}}';
        		console.log(chat_data);
        		ws.send( chat_data );
        		var dd = new Date();
	        	var date = formatDate(dd);
        		var chat_msg = date+":"+content+"\n";
	        	var old_msg = $('#chat-content').val();
				 $('#chat-content').val(old_msg+chat_msg);
        		console.log('send msg');
        	})
        	
        	function formatDate(now) {
			  var year = now.getFullYear(),
			  month = now.getMonth() + 1,
			  date = now.getDate(),
			  hour = now.getHours(),
			  minute = now.getMinutes(),
			  second = now.getSeconds();
			 
			  return year + "-" + month + "-" + date + " " + hour + ":" + minute + ":" + second;
			}
        </script>

前端代码大概如此,那么接下来开启服务

/usr/bin/php /var/www/html/aaa/server.php start

由于是测试,所以用户数据我都是写死的,方便调试,后续按照自己的需求,加入登录功能,绑定client_id就可以实现简单的IM聊天了,贴上自己写的简单的页面功能截图



后期通过优化界面,完善功能,一个简单的客服系统就可以出来了


版权声明:本文为teddy_dewei_lu原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。