关于Socket和WebSocket互相通信的疑问

现状:
1.通用workerman的socket提供安卓和IOS进行聊天。
2.网页端目前看来只能用websocket。

希望解决的问题:
是否可以有个什么办法。譬如中转服务,把socket和websocket的信息进行互相转发,或是还有提供更好的办法,麻烦给指个方向 ,谢谢了。
已邀请:

walkor

赞同来自: real joelhy

在Event.php中实现onGatewayMessage,使之支持双协议,方法就是通过协议的特点区分是哪种协议

由于和IOS通讯的协议是自己订制的,可以根据订制协议的特点比如协议是 json+回车 ,那么首字符应该是'{'(也可能是[,这里只是举个例子),而websocket协议首部第一个字节肯定不是'{‘,所以就可以通过首部这个字节来区分是IOS的协议还是websocket。当然你可以用其它方法区分协议。


public static function onGatewayMessage($buffer)
{
// 假如首部字节区分协议
if($buffer[0]=='{')
{
// IOS的协议
return yourIOSProtocol::check($buffer);
}
// websocket的协议
return WebSocket::check($buffer);
}



这样在Gateway层面上就能支持双协议了。
接下来还需要在Event::onConnect(如果版本小于2.1.3有的话) Event::onMessage上区分协议,方法类似,通过首部第一个字节


public static function onMessage($client_id, $buffer)
{
// 假如首部字节区分协议
if($buffer[0]=='{')
{
// IOS的协议
$protocol = 'IOS';
$message = yourIOSProtocol::decode($buffer);
}
else
{
// websocket的协议
$protocol = 'websocket';
$message = WebSocket::decode($buffer);
}

// 当客户端第一次发来数据时,需要根据协议存储客户端列表,IOS协议一组,WebSocket一组
if(!isset($_SESSION['protocol']))
{
// 保存session[protocol]说明已经将该client_id写到对应协议的client列表中了
$_SESSION['protocol'] = $protocol;
// 将client_id写入到对应协议的客户端列表
your_group_add_fun($protocol , $client);
// 保存这个client的协议到集中存储(例如memcache)中,以便私聊时用对应的协议给它发送数据
your_store_client_protocol($client_id, $protocol);
}

// [b][i]广播消息[/b][/i]
$new_message = "XXXXXXXXXXXXXXXXXX";

// 获取IOS客户端列表
$ios_client_id_array = your_get_client_array_func('IOS');
// 以IOS的协议向IOS客户端发送数据
Gateway::sendToAll(yourIOSProtocol::encode($new_message), $ios_client_id_array);

// 获取websocket客户端列表
$ws_client_id_array = your_get_client_array_func('WEBSOCKET');
// 以websocket协议向websocket客户端发送数据
Gateway::sendToAll(Websocket::encode($new_message), $websocket_client_id_array);

// [b][i] 私聊 [/b][/i]
$client_id_to_send = $message['to_client_id'];
$protocol = your_get_client_protocol($client_id_to_send);
if(‘IOS’ == $protocol)
{
$new_message = yourIOSProtocol::encode($new_message);
}
else
{
$new_message = Websocket::encode($new_message);
}
// 2.1.2版本为Gateway::sendToUid($client_id_to_send, $new_message);
Gateway::sendToClient($client_id_to_send, $new_message);
}


两种协议互相聊天的实现大概如上所述

walkor

赞同来自: tairen

新版本3.x可以很方便的设置多端口来支持多协议,心跳数据设置也会更加方便,会自动根据端口的协议传送不同的数据
目前2.x版本不能做到 不同的协议发送不同的ping.data

walkor

赞同来自:

--

tairen - s

赞同来自:

发送心跳数据也要分协议判断,这种情况下应该是两种格式的ping.data ,但在配置中是一个,感觉应该设置多个,然后在发送心跳数据是也需要判断协议,根据不同的协议发送不同的ping.data。。

该问题目前已经被锁定, 无法添加新回复