最近在一个linux机器上建了一个openfire,hostname为“A”,用spark的时候,在server处填写对方IP可以登录
但发现用qxmpp以“username@IP/resource”为JID登录时返回“Not Authorized”,但如果用“username@hostname/resource”为JID,则返回“socket error”
之前用“username@hostname/resource”为JID访问本地windows上架设的openfire没问题。
解决
1、对Java不熟,想请同事调一下spark是如何登录成功的,因为种种原因未成
2、短时间内没在openfire日志里找到spark登录时的JID
3、仔细分析qxmpp的底层代码,发现了socket连接和收发数据的地方,看到了最基本的xmpp通信xml
4、和同事讨论,同事建议修改本地host文件,将hostname映射成IP。当时没有接受这个建议,觉得不是最终解决办法,因为不可能去用户机器上修改host。(但事后看,这种做法是对调试有帮助的)
5、对比同一程序登录本地openfire和linux上的openfire过程中与服务器的xml。前面还能看懂,后面的就多是类似加密过的字符串,看了也没用。不过这个调研中最有价值的收获就是发现当和服务器建立socket连接后,服务器会返回hostname。
6、用wireshark分别收集spark登录linux上的openfire和自己程序登录同一服务器的数据包。同样,前面还能看,后面看不懂
7、无奈之下,用“Not Authorized openfire”之类的关键字搜索,发现了一些类似问题的资料
8、开始没看懂,后来忽然意识到,登录openfire肯定要用“username@hostname/resource”,而在此之前,一定要保证和服务器建立socket连接。借这种思路,先在qxmpp源代码里硬编码建立socket连接时所用的host为linux机器的ip,而登录还是用“username@hostname/resource”,成功。
备注
1、这种改法是权宜之计,感觉真正的做法应该利用建立连接时获得的hostname组成JID。