我做了一些挖掘和这里的交易。您从ejabberd_sm:get_session_pid
获取的值是该用户会话的ejabberd_c2s
进程。但ejabberd_c2s
完全不知道BOSH。您真正需要的是用户的BOSH会话ID,它由模块ejabberd_http_bind
维护。
尽我所能说,没有“好”的方法从ejabberd_c2s
中获取这些信息。最后我做这样的事情:
St = sys:get_status(Pid),
State = lists:nth(3, lists:nth(5, element(4, St))),
SocketState = element(2, State),
BindPid = element(2, element(3, SocketState)),
现在,这一切,让你在一天结束的是PID为ejabberd_http_bind
过程。您可以再次重复整个肮脏的生意,但在这里我建议作弊一点:
MS = ets:fun2ms(fun(#http_bind{pid=BP, id=Id}) when BP == BindPid -> Id end),
mnesia:dirty_select(http_bind, MS).
正如你所看到的,这是窘况丑陋。更好的方法是修改ejabberd_c2s
以接受将返回套接字信息的新类型sync_event
,并同样修改ejabberd_http_bind
以接受类似类型的事件以返回SID。当然,这些都将被包装在内部进行相关gen_fsm
调用的公共功能中。
说了这么多,我不确定BOSH SID真的会对你有什么好处。特别是,我不确定在这种情况下“脱机”和“断开”之间有什么区别。但无论如何,这就是你如何获得信息。
来源
2011-09-07 03:47:01
Dan
感谢您的信息Dan,我在我的问题中解释了为什么我需要SID,为了使用户“离线”强制需要,Disconnect将关闭我不想要的连接,我希望他们停留在连接上但显示为脱机状态。 – TilalHusain
毫无疑问,这只是一个演示,而且太粗糙,不适合在真实代码中使用。相反,你应该从被记录的'element(4,St)'开始,然后在列表中进行模式匹配以找到另一个以进程ID开头的列表的元素,然后在*列表中找到另一个模式匹配与来自'ejabberd_c2s'的'state'记录相匹配的元素等等。 – Dan
这种方法变得相当困难,而是我将所有的SID记录在mnesia表中,并将其用于我的目的。感谢所有的帮助。 – TilalHusain