2011-09-06 70 views
1

我想找到一種方法來提取使用PID和JID的bosh會話(ejabberd)的SID,以便我可以在ejabberd_sm:unset_presence中使用它,我已經遍尋搜索但找不到方法來做到這一點。使用會話PID和JID提取SID

基本上,我建立了一個使用Ejabberd和Strophe的聊天系統,我試圖實現的是當用戶在一個頁面上按下脫機按鈕時,與該JID相關的所有會話都需要脫機,我已經通過PID使用ejabberd_sm:get_session_pid但無法找到提取SID的方法。我也試過SID ! Disconnect,但完全斷開了我不想要的用戶。

如果有人做過這種工作請幫助我,也歡迎其他實施此類事情的想法。

謝謝

回答

0

我做了一些挖掘和這裏的交易。您從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真的會對你有什麼好處。特別是,我不確定在這種情況下「脫機」和「斷開」之間有什麼區別。但無論如何,這就是你如何獲得信息。

+0

感謝您的信息Dan,我在我的問題中解釋了爲什麼我需要SID,爲了使用戶「離線」強制需要,Disconnect將關閉我不想要的連接,我希望他們停留在連接上但顯示爲脫機狀態。 – TilalHusain

+0

毫無疑問,這只是一個演示,而且太粗糙,不適合在真實代碼中使用。相反,你應該從被記錄的'element(4,St)'開始,然後在列表中進行模式匹配以找到另一個以進程ID開頭的列表的元素,然後在*列表中找到另一個模式匹配與來自'ejabberd_c2s'的'state'記錄相匹配的元素等等。 – Dan

+0

這種方法變得相當困難,而是我將所有的SID記錄在mnesia表中,並將其用於我的目的。感謝所有的幫助。 – TilalHusain