Websockets,并识别唯一的对等[PHP]
我是websockets的新手.我刚刚完成了我的第一个多用途套接字服务器,它在同一个套接字中提供3种类型的消息.该服务器的用途如下:
chat messages real time market data user specific alerts 前两个功能运行良好,我非常高兴,但是在识别和链接与特定帐户的连接中的对等方时,我完全失去了,因此我可以向特定用户提供待处理的警报通知. 基本上,我将警报消息存储在数据库表中,如下所示: Table: uc_notifications account(varchar50) | message(varchar255) | id(primary,AI) | seen(default 0) 我想将对等体存储在一个表中,如下所示: uc_notification_peers account(varchar50) | peer_id(unique,varchar100) | id(primary,AI) 基本上,我遇到的问题是将对等方的信息存储在数据库中,并检索它,以便我可以在读取通知表时将消息发送给选择对等方.脚本中的其他所有内容都有效. 我尝试的第一件事是使用onopen将帐户名称传递给websocket.这会使websocket崩溃. 我尝试的下一件事是通过与ip地址有关的全局变量访问用户会话.也没有工作,导致所有帐户在同一个IP上收到消息(我在所有3个浏览器中测试localhost). 我尝试的最后一件事是第一种方法.我在开启事件上设置超时2秒,然后发送帐户消息.我终于能够在数据库中存储一个对等体了!但是,当我检查数据库时,我感到懊恼,它说(“资源ID#6).我尝试将$clients数组转换为全局,但每次都是空的.我google了一下,然后我尝试序列化数组.这一切工作直到我到达我发送消息给唯一同伴的部分. 这是发送消息的功能 function send_message_single_client($msg,$client) { @socket_write($client,$msg,strlen($msg)); return true; } 这里是我使用此函数将最后100条消息推送到新对等方的聊天框的示例. if (in_array($socket,$changed)) { $socket_new = socket_accept($socket); $clients[] = $socket_new; $header = socket_read($socket_new,1024); perform_handshaking($header,$socket_new,$host,$port); socket_getpeername($socket_new,$ip); $found_socket = array_search($socket,$changed); //need to push last 100 messages to new peer. $query = $mysqli->query("SELECT * FROM (SELECT * FROM uc_chat_msg WHERE `hidden`='0' ORDER BY `id` DESC LIMIT 100) as last100 ORDER BY id"); while($row = $query->fetch_assoc()) { $response_text = mask(json_encode(array('type'=>'usermsg','name'=>security($row["username"]),'message'=>security($row["message"]),'color'=>security($row["color"])))); send_message_single_client($response_text,$socket_new);//send old messages to the new client } $query->close(); unset($changed[$found_socket]); } 那是几个星期前,我把这个项目放在了后面,所以我可以继续前进并专注于其他事情.因为,我已经转向开发vps以适应应用程序不断增长的大小/复杂性.而不是PHP,我正在使用脸书HHVM,不相关,但我想提到它,因为它有一些怪癖,迫使我改变我的代码. 解决方法
我不知道PHP,但我认为这更像是一个方法问题,而不是编码问题.所以我希望这些来自推式架构经验的想法能带来一些启示.
识别用户 通过cookie识别: WebSockets使用HTTP握手来发送该源的cookie.您可以将临时ID(例如:GUID)附加到特殊会话cookie,每次用户在同一会话中重新连接时,都会重新发送该ID.只要您遵守同源策略,或者在HTTP握手响应中,您就可以从网站部署cookie. 通过给予令牌识别: 当WebSocket连接时,您可以从服务器发送包含临时ID的令牌的初始消息.如果连接断开,该令牌可以在重新连接时重新发送,但如果用户重新加载页面将被忘记,除非它保存在本地存储或任何其他类型的浏览器存储中. 关于临时ID的说明 临时ID如何映射到特定用户或帐户,是您不希望泄露到Web的实现细节.因此,请勿使用该信息来标识您的WS连接. 您应该保留一个“会话”注册表,将临时ID映射到帐户,可能是从内存字典中映射到数据库上的表.由您,您的要求和您的服务决定.此元素必须保持对WebSocket连接的引用,因此您可以在需要时通过临时ID检索它. 切勿泄漏内部细节,特别是帐户ID(因为它们不会更改). 接收消息 从WebSocket接收消息时,必须使用您保留的“会话”信息以及实际的消息内容创建包含发件人帐户的消息对象.然后,将此消息对象传递给将决定要执行的操作的业务逻辑. 在发送消息之前 要发送消息,您必须先定义几个元素: 存在: 哪些帐户在线?将“会话”存储与帐户表合并.当连接断开时,您应该删除drop用户会话. 属于: 哪些帐户属于特定群组或信号?您必须根据您的要求进行设计.一些组可以预定义并在“帐户”实体中指示,一些其他组可以是动态的,就像他属于聊天室一样.在任何情况下,您需要另一个将“组”映射到“帐户”的元素 发送消息 当您的业务逻辑决定要发送消息时,无论是作为对传入消息的响应,作为定时操作,还是主动或其他……它必须决定必须发送哪个用户帐户,用户帐户或用户组. 然后,使用您保留的会话信息,收集必须接收该消息的临时ID列表,然后是必须转发该消息的WebSockets列表,最后将消息发送到该列表的每个WS. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |