GatewayWorker与Thinkphp3.2.3开发即时通讯详细流程

GatewayWorker是workerman的框架,里面封装了很多好用的方法,比直接使用workerman要方便的多。尤其在和其他MVC框架对接时,就更加方便了。

Linux和Mac os用户下载:http://www.workerman.net/download/GatewayWorker.zip
Windows用户下载:http://www.workerman.net/download/GatewayWorker-for-win.zip

GatewayClient客户端源码:https://github.com/walkor/GatewayClient
GatewayWorker1.0请使用1.0版本的GatewayClient
GatewayWorker2.0.1-2.0.4请使用2.0.4版本的GatewayClient
GatewayWorker2.0.5-2.0.6版本请使用2.0.6版本的GatewayClient
GatewayWorker2.0.7版本请使用 2.0.7版本的GatewayClient
GatewayWorker3.0.0及以上版本请使用 3.0.0版本的GatewayClient
GatewayWorker3.0.8及以上版本请使用 3.0.13版本的GatewayClient

GatewayClient3.0.0开始支持composer并加了命名空间GatewayClient
查看GatewayWorker版本方法:https://www.kancloud.cn/walkor/gateway-worker/326159

注意
1、下载后GatewayClient目录可以放在项目中的任意位置,只要项目能引用到GatewayClient/Gateway.php即可。
2、如果GatewayClient和GatewayWorker不是在同一台服务器上,则需要先将start_gateway.php中的lanIp改成当前服务器的内网ip(如果不在一个内网可改成公网ip)。注意,无论何时lanIp都不能写成0.0.0.0,否则将无法通讯。
3、如果GatewayClient和GatewayWorker不是在同一台服务器上,还要设置防火墙(云服务器的话还要设置安全组)让以下端口可以被GatewayClient所在服务器访问:
(1)start_gateway.php中的$ gateway->startPort起始的几个端口(要开放的端口个数和$ gateway->count有关)。
(2)start_register.php中的Register服务端口
4、如果GatewayClient和GatewayWorker在同一台服务器上运行,则不用做任何更改,直接按照示例使用GatewayClient即可。
5、通过GatewayClient发送的数据不会经过Event.php,而是直接经由Gateway进程转发给客户端。
6、GatewayClient无法接收客户端发来的数据。
7、GatewayClient无法直接用$_SESSION变量来操作GatewayWorker的session,但可以用Gateway::setSession/getSession/updateSession等接口操作GatewayWorker的session。

Linux版本启动方式:运行start.php文件
Windows版本启动方式:运行start_for_win.bat批处理文件

GatewayWorker下载下来后,需要关注的只有一个文件,就是Applications/YourApp/Events.php,所有程序业务逻辑都在这里。

GatewayWorker的目录结构:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

方法一:
第一步:
1、下载tp3.2.3、GatewayWorker、GatewayClient;
2、解压后把Gatewayworker放在tp的根目录下;

第二步:
1、将GatewayClient中的Gateway.php重命名为Gateway.class.php;
2、将Gateway.class.php中的

namespace GatewayClient;

修改为:

namespace Org\Util;

3、修改Gateway.class.php第35行的$registerAddress的端口号,使其和GatewayWorker/Application/YourApp/下的三个start_文件里面的“服务注册地址”下端口号一致;
4、保存Gateway.class.php后将该文件放于tp框架的ThinkPHP/Library/Org/Util文件夹下(然后可将GatewayClient文件夹删除,其他文件不需要);

第三步:
1、 将GatewayWorker\Applications\YourApp中start_gateway.php的第24行Gateway括号内的代码修改为(“websocket://后面的不变”);
2、将GatewayWorker\Applications\YourApp中Events.php的第40行修改为:

Gateway::sendToClient($client_id,json_encode(array('client_id'=>$client_id)));

第四步:在tp控制器Index.class.php文件中内容如下:

<?php
	namespace Home\Controller;
	use Think\Controller;
	class IndexController extends Controller {
	  	public function index() { 
	  		//$this->uid = I('uid'); 									//发信人ID,获取登录时ID,和下方message()中的I('uid')不同
	  		$this->uid = 520;											//暂用固定值
	  		session('uid', $this->uid); 
	  		$this->display(); 
	  	} 
	  	function bind() { 
	  		$uid = session('uid'); 										//发信人ID
	  		$client_id = I('client_id'); 
	  		$gateway = new \Org\Util\Gateway(); 
	  		$gateway->bindUid($client_id, $uid); 
	  		$message = '绑定成功' . $uid . '-' . $client_id; 
	  		$gateway->sendToUid($uid, $message); 
	  	} 
	  	function message() { 
	  		$to_uid = I('uid'); 										//收信人ID
	  		$message = I('msg'); 
	  		$gateway = new \Org\Util\Gateway(); 
	  		$data['msg'] = $message; 
	  		$data['from_uid'] = session('uid'); 
	  		$data['to_uid'] = $to_uid; 
	  		$gateway->sendToUid($to_uid, json_encode($data)); 			//发给对方 
	  		$gateway->sendToUid($data['from_uid'], json_encode($data));	//发给自己 
	  		echo json_encode($data); 
	  	}
	}

视图文件index.html文件内容为:

<!DOCTYPE HTML> 
<html> 
<head> 
	<meta charset="utf-8"> 
	<title>chatroom</title> 
	<script type="text/javascript" src="http://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"/></script> 
	<script type="text/javascript"> 
		// 打开一个web socket 
		var ws = new WebSocket("ws://127.0.0.1:8282"); 
		ws.onopen = function () { 

		}; 
		ws.onmessage = function (evt) { 
			var received_msg = evt.data; 
			alert("数据已接收..." + received_msg); 
			var jmsg = JSON.parse(received_msg); 
			if (jmsg.from_uid > 0) { 
				var t_msg = '<li>' + jmsg.from_uid + ' 说:' + jmsg.msg + '</li>'; 
				$("#message").append(t_msg); 
			} 
			if (jmsg.client_id.length != 0) { 
				$.post("{:U('bind')}", {client_id: jmsg.client_id}, function (data) { }); 
			} 
		} 
	</script> 
</head> 
<body> 
<ul id="message"> </ul> 
<div> 
<span>收信人ID:</span>
	<input name="uid" value="1" > <!-- value值为收信人ID -->
	<input name="msg" value="" size="50"> 
	<button type="button" id="send" >发送</button> 
</div> 
<script> 
	$(function () { 
		$("#send").click(function () { 
			var uid = $('input[name="uid"]').val(); 
			var msg = $('input[name="msg"]').val(); 
			$.post("{:U('message')}", {uid: uid, msg: msg}, function (data) { $('input[name="msg"]').val(''); }); 
		}); 
	}); 
</script> 
</body> 
</html>

第五步:
1、双击启动GatewayWorker文件下的.bat文件;
2、然后在浏览器中访问文件地址,如:http://localhost:88/liaotian/index.php/Home/index/index

另外:如果在本地运行此文件的话,因为你的电脑ip是唯一的,所以你的uid是唯一的,不会因为你打开两个浏览器就可以实现对话了。不过当你能在一个浏览器上收到自己发出的消息,基本没问题了。

目前还没解决的问题:如何在windows下,不手动运行.bat文件,使其自动运行gatewayworker环境(Linux可用守护进程,但Windows只能一直开着.bat文件或添加成服务,添加成服务见下方)。

方法二:
a)下载并安装thinkphp。
b)下载并解压GatewayClient(最后可将GatewayClient文件夹删除)。
c)将GatewayClient中的Gateway.php重命名为Gateway.class.php。
d)将Gateway.php中的

namespace GatewayClient;

修改为:

namespace Org\Util;

e)修改Gateway.php第35行的$ registerAddress的端口号,使其和GatewayWorker/Application/YourApp/下的三个start_文件里面的“服务注册地址”下端口号一致。
f)保存Gateway.php后将该文件放于tp框架的ThinkPHP/Library/Org/Util文件夹下(然后可将GatewayClient文件夹删除,文件夹中其他文件不需要)。
g)下载GatewayWorker,将下载的压缩包解压,将Applications/Yourapp中的文件全部复制到thinkphp的application文件夹下的新建文件夹中,文件夹取名为push(也可直接放入Home或Admin中)。
h)将GatewayWorker/Applications/Yourapp中start_gateway.php的第24行Gateway括号内的代码修改为(“websocket://后面的不变”);
i)将GatewayWorker/Applications/Yourapp中Events.php的第40行修改为:

Gateway::sendToClient($client_id,json_encode(array('client_id'=>$client_id)));

j)将解压后的GatewayWorker文件夹中的start_for_win.bat复制到thinkphp的根目录,即与application同级的目录。
k)右键start_for_win.bat编辑,将里面的目录改成自己的目录,这里改为:

php application\push\start_register.php application\push\start_gateway.php application\push\start_businessworker.php
Pause

l)保存退出。双击运行。

Windows如何添加服务:
1、首先下载两个小程序instsrv.exe和srvany.exe
将instsrv.exe和srvany.exe拷贝到"C:\Windows\system32"目录下(如果是64bit系统,则将其拷贝到C:\Windows\SysWOW64),此处拷贝到"C:\Windows"下,用instsrv.exe安装srvany.exe。
2、创建Windows服务
打开DOS命令窗口到达该目录下输入命令,并回车如图:

在这里插入图片描述
计算机->右键->管理->服务,可看到:

在这里插入图片描述
3、修改注册表
“运行”中写命令“regedit”回车,打开注册表编辑器
a、定位到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\UnityCacheServer
b、在UnityCacheServer右键->新建->项, 命名Parameters(此名称固定)
c、右键Parameters->新建->字符串值,命名Application(此名称固定)
d、右键Application->新建->修改,写入应用程序或命令脚本等的绝对路径(包括盘符和文件的尾缀名) 点击确定

在这里插入图片描述
4、重启电脑可以看到我们的Windows服务自动运行了。即自动执行了RunWin.cmd。
5、删除服务的方法:
今后若想移除上面新建的Windows服务,首先停止该服务,然后到目录C:\Windows\下执行命令:
instsrv UnityCacheServer remove 回车,见下图即表示删除成功。

在这里插入图片描述

上传服务器后的设置:
1、服务器防火墙添加端口8282的入站规则(详见百度);
2、修改所有HTML页面中的var ws = new WebSocket(“ws://127.0.0.1:8282”);为var ws = new WebSocket(“ws://服务器IP:8282”);
3、如果打开页面GatewayWorker仍无反应(未绑定client_id即可证明),则在本地和服务器运行cmd,输入:telnet 服务器IP 端口号,回车。
4、如果显示下图,说明telnet服务器和客户端未启用(如何启用见百度):

在这里插入图片描述
如果显示下图,说明已开启telnet客户端和服务器,但未映射端口:

在这里插入图片描述
如果只显示有光标说明已正常映射端口,可正常使用,如下图:

在这里插入图片描述
5、如果仍不能映射端口,则可能是服务器空间服务商屏蔽,请联系服务商客服开启端口。

猜你喜欢

转载自blog.csdn.net/qq_38882327/article/details/89352916