IM即时通信多房间聊天室仿微信聊天(一)

2022-03-05 14:55:21 浏览数 (1)

IM即时通信多房间聊天室仿微信聊天(概述)

最近客户项目里面需要嵌入一个聊天室功能来打造社区生态,增加用户黏度。为了打造单项的引流目的,剔除了聊天中的加好友和私聊功能。这个目前比较忙不考虑短期内更新。

聊天室整体风格都是仿微信界面的,包括了发文字、语音、图片和视频消息。不依赖日任何收费第三方组件!可以拿去即用

下面是效果图:在这里插入图片描述在这里插入图片描述
1、实现通信

聊天室最重要的一步当然是实现通信了,这里我用的是基于workerman的Gateway Worker链接已经给了,不熟悉的可以去看看他的官方文档;

由于我的项目中用户的头像、昵称包括房间的权限啊之类的信息都是深度定制依赖于整个app的,所以我这边考虑的是将GatewayWorker与后台服务结合的方式,这样子直接将Gateway服务作为分发工具了而逻辑的处理都交给自己的后台服务去做就行了。

下面讲讲具体的集成方法:

(1)、GatewayClient安装:**

将下载好的GatewayClient集成在自己后台项目中,具体放在什么目录根据实际情况而定,总之后面引入的时候自己知道存放的路径能将它正确引入就可以了;

(2)、自己项目中引入,这里我用的是php,引入页面如下:

代码语言:php复制
namespace ApiController;
use GatewayClientGateway;
require_once dirname(__DIR__) . "/libs/GatewayClient/Gateway.php";
use thinkLog;

(3)、启动GatewayWorker服务

在启动GatewayWorker之前呢我们需要查看一下它的几个重要的端口配置

端口的配置都在文件名为start_gateway.php这个文件中主要配置两个端口

代码语言:php复制
// gateway 进程,这里使用Text协议,可以用telnet测试
$gateway = new Gateway("websocket://0.0.0.0:23426");
// gateway名称,status方便查看
$gateway->name = 'nywSocket';
// gateway进程数
$gateway->count = 1;
// 本机ip,分布式部署时使用内网ip
$gateway->lanIp = '127.0.0.1';
// 内部通讯起始端口,假如$gateway->count=4,起始端口为4000
// 则一般会使用4000 4001 4002 4003 4个端口作为内部通讯端口 
$gateway->startPort = 2900;
// 服务注册地址
$gateway->registerAddress = '127.0.0.1:1238';

$gateway配置的是客户端与其进行websocket连接的服务器地址和端口

$gateway->registerAddress是服务端与之通信的服务器地址和端口

配置好了之后就是正式启动了,至于怎么启动,官方文档已经讲的很清楚了:

windows:直接双击运行start_for_win.bat文件

Linux:首先进入start.php所在的文件目录然后执行命令

代码语言:text复制
php start.php start

就可以启动GatewayWorker服务了。

但是注意一点!既然是做即时通信,那我们肯定是希望这个服务一直保持在后台运行,但是上面的命令执行完之后,当我们关闭服务器终端命令窗口,则服务也会立刻停止,所以我们需要执行一下命令来运行服务:

代码语言:text复制
php start.php start -d

这样当我们关闭终端之后服务仍然保持在后台运行不中断

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

这个很简单直接上代码:

代码语言:html复制
let ws = new WebSocket('ws://118.195.189.231:23426');

118.195.189.231是我部署GatWayWorker的服务器地址,实际你们自己项目中替换成你们自己的地址就可以了

(5)、GatewayWorker发现有页面发起连接时,将对应连接的client_id发给网站页面

在GateWayWorker的Event.php文件中进行操作:

代码语言:php复制
 /**
     * 当客户端连接时触发
     * 如果业务不需此回调可以删除onConnect
     * 
     * @param int $client_id 连接id
     */
    public static function onConnect($client_id)
    {
		Gateway::sendToClient($client_id, json_encode(array(
		    'action_type'      => 'init',
		    'client_id' => $client_id
		)));
    }

我们为什么需要这个client_id呢,其实是为了后续的多房间聊天功能准备的(后续讲到多房间功能的时候在详细讲)

关于client_id:client_id固定为20个字符的字符串,用来全局标记一个socket连接,每个客户端连接都会被分配一个全局唯一的client_id;

client_id不能自定义,由GatewayWorker自动生成;

如果client_id对应的客户端连接断开了,那么这个client_id也就失效了。当这个客户端再次连接到Gateway时,将会获得一个新的client_id。也就是说client_id和客户端的socket连接生命周期是一致的。

client_id一旦被使用过,将不会被再次使用,也就是说client_id是不会重复的,即使分布式部署也不会重复;

只要有client_id,并且对应的客户端在线,就可以调用Gateway::sendToClient($client_id, $data)等方法向这个客户端发送数据;

(6)、客户端接收GateWayWorker发送过来的消息

代码语言:php复制
onmessage(){
	ws.onmessage = e => {
		let msg = JSON.parse(e.data);
		console.log(msg)
		let action_type = msg.action_type;
	};
}

打印msg我们就可以看到就是步骤(5)中GateWay发送过来的消息:

代码语言:php复制
'action_type' => 'init',
'client_id' => $client_id

至此我们就实现了GatWayWorker和客户端的基本连接了...

时间有限其他部分的详细介绍会陆续更新,希望大家一起交流!

下一节讲IM即时通信多房间聊天室仿微信聊天(服务器自定义处理客户端消息)

0 人点赞