xmpp-多人聊天实例
更新时间:2024-04-13 05:47:01 阅读量: 综合文库 文档下载
- xmpp多点登录推荐度:
- 相关推荐
一直想写东西,但是上班不能在CSDN上写东西。下班回家又忙着学Iphone开发,唉,两个个字,忒忙。今天就写写Smack的聊天室功能吧。 先上代码:
view plain
1. import java.io.BufferedReader; 2. import java.io.InputStreamReader; 3. import java.util.ArrayList; 4. import java.util.Collection; 5. import java.util.Iterator; 6. import java.util.List; 7.
8. import org.jivesoftware.smack.Chat;
9. import org.jivesoftware.smack.ConnectionConfiguration; 10. import org.jivesoftware.smack.MessageListener; 11. import org.jivesoftware.smack.PacketListener; 12. import org.jivesoftware.smack.SmackConfiguration; 13. import org.jivesoftware.smack.XMPPConnection; 14. import org.jivesoftware.smack.XMPPException; 15. import org.jivesoftware.smack.packet.Message; 16. import org.jivesoftware.smack.packet.Packet;
17. import org.jivesoftware.smack.provider.ProviderManager; 18. import org.jivesoftware.smackx.Form; 19. import org.jivesoftware.smackx.FormField;
20. import org.jivesoftware.smackx.ServiceDiscoveryManager;
21. import org.jivesoftware.smackx.muc.DefaultParticipantStatusListener; 22. import org.jivesoftware.smackx.muc.DefaultUserStatusListener; 23. import org.jivesoftware.smackx.muc.DiscussionHistory; 24. import org.jivesoftware.smackx.muc.HostedRoom;
25. import org.jivesoftware.smackx.muc.InvitationListener;
26. import org.jivesoftware.smackx.muc.InvitationRejectionListener; 27. import org.jivesoftware.smackx.muc.MultiUserChat; 28. import org.jivesoftware.smackx.muc.RoomInfo;
29. import org.jivesoftware.smackx.muc.SubjectUpdatedListener; 30. import org.jivesoftware.smackx.packet.ChatStateExtension; 31. import org.jivesoftware.smackx.packet.DiscoverInfo; 32. import org.jivesoftware.smackx.packet.DiscoverItems; 33. import org.jivesoftware.smackx.packet.OfflineMessageInfo; 34. import org.jivesoftware.smackx.packet.OfflineMessageRequest; 35. import org.jivesoftware.smackx.provider.AdHocCommandDataProvider; 36. import org.jivesoftware.smackx.provider.BytestreamsProvider; 37. import org.jivesoftware.smackx.provider.DataFormProvider;
38. import org.jivesoftware.smackx.provider.DiscoverInfoProvider; 39. import org.jivesoftware.smackx.provider.DiscoverItemsProvider; 40. import org.jivesoftware.smackx.provider.IBBProviders; 41. import org.jivesoftware.smackx.provider.MUCAdminProvider; 42. import org.jivesoftware.smackx.provider.MUCOwnerProvider; 43. import org.jivesoftware.smackx.provider.MUCUserProvider;
44. import org.jivesoftware.smackx.provider.StreamInitiationProvider; 45. import org.jivesoftware.smackx.provider.VCardProvider;
46. import org.jivesoftware.smackx.provider.XHTMLExtensionProvider; 47.
48. public class TestSmack2 {
49. public static void main(String[] args) {XMPPConnection.DEBUG_ENABLED = true; 50. final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(\
PC2010102716\, 5222, \);
51. connectionConfig.setSASLAuthenticationEnabled(false); 52. ProviderManager pm = ProviderManager.getInstance(); 53. configure(pm); 54. try {
55. XMPPConnection connection = new XMPPConnection(connectionConfig); 56. connection.connect();//连接 57. initFeatures(connection);
58. connection.login(\, \);//登陆 59. //聊天室
60. //MultiUserChat multiUserChat = new MultiUserChat(connection, new Invitati
onListener() {}); 61. //查找服务
62. System.out.println(connection.getServiceName());
63. List
ection);
64. for (Object aCol : col) {
65. String service = (String) aCol; 66. //查询服务器上的聊天室
67. Collection
, service);
68. for(HostedRoom room : rooms) { 69. //查看Room消息
70. System.out.println(room.getName() + \ +room.getJid()); 71. RoomInfo roomInfo = MultiUserChat.getRoomInfo(connection, room.get
Jid());
72. if(roomInfo != null) {
73. System.out.println(roomInfo.getOccupantsCount() + \ + room
Info.getSubject()); 74. } 75. }
76. } 77.
78. /*---创建默认配置的聊天室 --- 79. 先看看官方的文档:
80. Creates a new multi user chat with the specified connection and room name.
Note: no
81. * information is sent to or received from the server until you attem
pt to
82. * {@link #join(String) join} the chat room. On some server implementa
tions,
83. * the room will not be created until the first person joins it 84. * 最重要一句:直到用户调用join方法的时候聊天室才会被创建 85. */
86. MultiUserChat muc = new MultiUserChat(connection, \
10102716\);
87. muc.create(\);
88. muc.sendConfigurationForm(new Form(Form.TYPE_SUBMIT)); 89.
90. //----创建手动配置聊天室----
91. muc = new MultiUserChat(connection, \);
92.
93. //销毁聊天室
94. //muc.destroy(\ 95. muc.create(\); 96. //获取聊天室的配置表单
97. Form form = muc.getConfigurationForm(); 98. //根据原始表单创建一个要提交的新表单
99. Form submitForm = form.createAnswerForm(); 100. //向提交的表单添加默认答复
101. for(Iterator
103. if(!FormField.TYPE_HIDDEN.equals(field.getType()) && field.getVariable
() != null) {
104. submitForm.setDefaultAnswer(field.getVariable()); 105. } 106. }
107. //重新设置聊天室名称
108. submitForm.setAnswer(\, \); 109. //设置聊天室的新拥有者
110. List
112. submitForm.setAnswer(\, owners); 113. //设置密码
114. submitForm.setAnswer(\, true); 115. submitForm.setAnswer(\, \); 116. //设置描述
117. submitForm.setAnswer(\, \新创建的reserved聊天室
\);
118. //设置聊天室是持久聊天室,即将要被保存下来
119. //submitForm.setAnswer(\ 120. //发送已完成的表单到服务器配置聊天室 121. muc.sendConfigurationForm(submitForm); 122.
123. //加入聊天室(使用昵称喝醉的毛毛虫 ,使用密码ddd)
124. muc = new MultiUserChat(connection, \); 125. muc.join(\喝醉的毛毛虫\, \); 126.
127. //监听消息
128. muc.addMessageListener(new PacketListener() { 129. @Override
130. public void processPacket(Packet packet) { 131. Message message = (Message) packet;
132. System.out.println(message.getFrom() + \ + message.getBody());
;
133. } 134. }); 135.
136. //muc = new MultiUserChat(connection, \ 137. //muc.join(\喝醉的毛毛虫\ 138.
139. //加入聊天室(使用昵称喝醉的毛毛虫 ,使用密码ddd)并且获取聊天室里最后5条信息, 140. //注:addMessageListener监听器必须在此join方法之前,否则无法监听到需要的5条消
息
141. muc = new MultiUserChat(connection, \); 142. DiscussionHistory history = new DiscussionHistory(); 143. history.setMaxStanzas(5); 144. muc.join(\喝醉的毛毛虫
\, \, history, SmackConfiguration.getPacketReplyTimeout()); 145.
146. //监听拒绝加入聊天室的用户
147. muc.addInvitationRejectionListener(new InvitationRejectionListener() { 148. @Override
149. public void invitationDeclined(String invitee, String reason) { 150. System.out.println(invitee + \ + reason
);
151. } 152. });
153. //邀请用户加入聊天室
154. muc.invite(\, \大家来谈谈人生\); 155. //监听邀请加入聊天室请求
156. MultiUserChat.addInvitationListener(connection, new InvitationListener() {
157. @Override
158. public void invitationReceived(XMPPConnection conn, String room, Strin
g inviter, String reason, String password, Message message) { 159. //例:直接拒绝邀请
160. MultiUserChat.decline(conn, room, inviter, \你丫很闲啊!\); 161. } 162. }); 163. 164.
165. //根据roomJID获取聊天室信息
166. RoomInfo roomInfo = MultiUserChat.getRoomInfo(connection, \
pc2010102716\);
167. System.out.println(roomInfo.getRoom() + \ + roomInfo.getSubject() + \
+ roomInfo.getOccupantsCount()); 168.
169. //判断用户是否支持Multi-User聊天协议 170. //注:需要加上资源标识符
171. boolean supports = MultiUserChat.isServiceEnabled(connection, \
0102716/spark\);
172. //获取某用户所加入的聊天室 173. if(supports) {
174. Iterator
, \);
175. while(joinedRooms.hasNext()) {
176. System.out.println(\ + joinedRooms.next());
177. } 178. } 179.
180. //与聊天室用户私聊
181. Chat chat = muc.createPrivateChat(\飞鸟
\, new MessageListener() { 182. @Override
183. public void processMessage(Chat chat, Message message) {
184. System.out.println(\ + messa
ge.getFrom() + \ + message.getBody()); 185. } 186. });
187. chat.sendMessage(\今天不用加班吧?\);
188.
189. //改变聊天室主题
190. muc.addSubjectUpdatedListener(new SubjectUpdatedListener() { 191. @Override
192. public void subjectUpdated(String subject, String from) {
193. System.out.println(\ + subject +\ + from)
;
194. } 195. });
196. //muc.changeSubject(\ 197.
198. /*一个成员可能有四种角色:
199. 1:主持者(Moderator) (权限最大的角色,管理其他成员在聊天室中的角色 200. 2:参与者(Participant
201. 3:游客 (Visitor) (不能向所有成员发送消息) 202. 4:无(没有角色)(NONE) 203. */ 204.
205. /*聊天室用户可以有5种从属关系 206. * 1、所有者 Owner 207. * 2、管理员 Admin 208. * 3、成员 Member 209. * 4、被驱逐者 Outcast 210. * 5、无(不存在从属关系) None 211. */ 212.
213. //配置聊天室为Moderated聊天室 214. form = muc.getConfigurationForm();
215. Form answerForm = form.createAnswerForm();
216. answerForm.setAnswer(\, \); 217. muc.sendConfigurationForm(answerForm); 218.
219. //监听自己的状态变更和事件
220. muc.addUserStatusListener(new DefaultUserStatusListener() { 221. @Override
222. public void voiceRevoked() { 223. super.voiceRevoked();
224. System.out.println(\你被禁言了!\); 225. } 226.
227. @Override
228. public void voiceGranted() { 229. super.voiceGranted();
230. System.out.println(\你被批准发言了!\);
231. } 232.
233. @Override
234. public void membershipGranted() { 235. super.membershipGranted();
236. System.out.println(\你被赋予了Member权限\); 237. } 238.
239. @Override
240. public void membershipRevoked() { 241. super.membershipRevoked();
242. System.out.println(\你被解除了Member权限\); 243. } 244.
245. @Override
246. public void adminGranted() { 247. super.adminGranted();
248. System.out.println(\你被赋予了管理员权限\); 249. } 250.
251. @Override
252. public void adminRevoked() { 253. super.adminRevoked();
254. System.out.println(\你被解除了管理员权限\); 255. } 256. //...... 257. });
258. //房主(Owner)批准test3发言权
259. muc.grantVoice(\); 260.
261. //监听他人状态变更
262. muc.addParticipantStatusListener(new DefaultParticipantStatusListener() {
263.
264. @Override
265. public void voiceGranted(String participant) { 266. super.voiceGranted(participant);
267. System.out.println(participant + \被批准发言了!\); 268. } 269.
270. @Override
271. public void voiceRevoked(String participant) { 272. super.voiceRevoked(participant);
273. System.out.println(participant + \被禁言了!\);
274. } 275.
276. @Override
277. public void membershipRevoked(String participant) { 278. super.membershipRevoked(participant); 279. } 280.
281. @Override
282. public void adminGranted(String participant) { 283. super.adminGranted(participant); 284. } 285.
286. @Override
287. public void adminRevoked(String participant) { 288. super.adminRevoked(participant); 289. } 290.
291. }); 292.
293. //房主(Owner)批准test3管理员特权 294. muc.grantAdmin(\); 295. 296.
297. //发送消息
298. BufferedReader cmdIn = new BufferedReader(new InputStreamReader(System.in)
);
299. while(true) { 300. try {
301. String cmd = cmdIn.readLine(); 302. if(\.equalsIgnoreCase(cmd)) { 303. break; 304. }
305. }catch(Exception ex) { 306. } 307. }
308. connection.disconnect(); 309. System.exit(0); 310. } catch (Exception e) { 311. e.printStackTrace(); 312. } 313. } 314.
315. public static List
nnection) throws Exception {
316. List
317. ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstance
For(connection);
318. DiscoverItems items = discoManager.discoverItems(server);
319. for (Iterator
320. DiscoverItems.Item item = (DiscoverItems.Item)it.next();
321. if (item.getEntityID().startsWith(\) || item.getEntityID().
startsWith(\)) {
322. answer.add(item.getEntityID()); 323. } 324. else { 325. try {
326. DiscoverInfo info = discoManager.discoverInfo(item.getEntityID
());
327. if (info.containsFeature(\)) {
328. answer.add(item.getEntityID()); 329. } 330. }
331. catch (XMPPException e) { 332. } 333. } 334. }
335. return answer; 336. } 337. 338.
339. private static void configure(ProviderManager pm) { 340. // Service Discovery # Items
341. pm.addIQProvider(\, \, new Discov
erItemsProvider());
342. // Service Discovery # Info
343. pm.addIQProvider(\, \, new Discove
rInfoProvider()); 344.
345. // Service Discovery # Items
346. pm.addIQProvider(\, \, new Discov
erItemsProvider());
347. // Service Discovery # Info
348. pm.addIQProvider(\, \, new Discove
rInfoProvider()); 349.
350. //Offline Message Requests
351. pm.addIQProvider(\,\, new OfflineMe
ssageRequest.Provider());
352. //Offline Message Indicator
353. pm.addExtensionProvider(\,\
, new OfflineMessageInfo.Provider()); 354. 355. //vCard
356. pm.addIQProvider(\,\, new VCardProvider()); 357.
358. //FileTransfer
359. pm.addIQProvider(\,\, new StreamInitiationPro
vider());
360. pm.addIQProvider(\,\, new
BytestreamsProvider());
361. pm.addIQProvider(\,\, new IBBProvi
ders.Open());
362. pm.addIQProvider(\,\, new IBBProv
iders.Close());
363. pm.addExtensionProvider(\,\, new I
BBProviders.Data()); 364. //Data Forms
365. pm.addExtensionProvider(\, \, new DataFormProvider()); 366. //Html
367. pm.addExtensionProvider(\, \, new
XHTMLExtensionProvider()); 368. //Ad-Hoc Command
369. pm.addIQProvider(\, \, new AdH
ocCommandDataProvider()); 370. // Chat State
371. ChatStateExtension.Provider chatState = new ChatStateExtension.Provider(); 372. pm.addExtensionProvider(\, \, cha
tState);
373. pm.addExtensionProvider(\, \,
374. chatState);
375. pm.addExtensionProvider(\, \, cha
tState);
376. pm.addExtensionProvider(\, \, c
hatState);
377. pm.addExtensionProvider(\, \, chatS
tate);
378. //MUC User,Admin,Owner
379. pm.addExtensionProvider(\, \, new MUCUse
rProvider());
380. pm.addIQProvider(\, \, new MUCAdmin
Provider());
381. pm.addIQProvider(\, \, new MUCOwner
Provider()); 382. } 383.
384. private static void initFeatures(XMPPConnection xmppConnection) { 385. ServiceDiscoveryManager.setIdentityName(\); 386. ServiceDiscoveryManager.setIdentityType(\);
387. ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(xmppConne
ction);
388. if(sdm == null) {
389. sdm = new ServiceDiscoveryManager(xmppConnection); 390. }
391. sdm.addFeature(\); 392. sdm.addFeature(\); 393. sdm.addFeature(\); 394. sdm.addFeature(\); 395. sdm.addFeature(\);
396. sdm.addFeature(\); 397. sdm.addFeature(\); 398. sdm.addFeature(\); 399. sdm.addFeature(\); 400. sdm.addFeature(\);
401. sdm.addFeature(\); 402. sdm.addFeature(\);
403. sdm.addFeature(\); 404. sdm.addFeature(\);
405. sdm.addFeature(\); 406. sdm.addFeature(\); 407. } 408. 409. }
上面有两张Spark客户端的聊天室列表占有者一列不同的原因:当使用以下代码获取时不能获取occupantsCount和subject的值:
view plain
1. System.out.println(roomInfo.getOccupantsCount() + \ + roomInfo.getSubject(
));
这是由于Openfire端有个bug(暂且这样说吧,我不知为什么Openfire这样做).首先修改Smack的一个bug,修改RoomInfo类的RoomInfo(DiscoverInfo info) 方法:
view plain
1. Iterator
3. this.subject = values.next(); 4. } 5. else {
6. this.subject = \;
7. }
改为:
view plain
1. final FormField subjField = form.getField(\); 2. this.subject = subjField == null ? \ : subjField.getValues().next();
修改Openfire的源码,org/jivesoftware/openfire/muc/spi/MultiUserChatServiceImpl类的public DataForm getExtendedInfo(String name, String node, JID senderJID) 方法:
view plain
1. /*final FormField fieldOcc = dataForm.addField(); */ 2. fieldSubj.setVariable(\);
3. fieldSubj.setLabel(LocaleUtils.getLocalizedString(\
nts\));
4. fieldSubj.addValue(Integer.toString(room.getOccupantsCount())); 5.
改为:
view plain
1. final FormField fieldOccu= dataForm.addField(); 2. fieldOccu.setVariable(\);
3. fieldOccu.setLabel(LocaleUtils.getLocalizedString(\)); 4. fieldOccu.addValue(Integer.toString(room.getOccupantsCount()));
7. }
改为:
view plain
1. final FormField subjField = form.getField(\); 2. this.subject = subjField == null ? \ : subjField.getValues().next();
修改Openfire的源码,org/jivesoftware/openfire/muc/spi/MultiUserChatServiceImpl类的public DataForm getExtendedInfo(String name, String node, JID senderJID) 方法:
view plain
1. /*final FormField fieldOcc = dataForm.addField(); */ 2. fieldSubj.setVariable(\);
3. fieldSubj.setLabel(LocaleUtils.getLocalizedString(\
nts\));
4. fieldSubj.addValue(Integer.toString(room.getOccupantsCount())); 5.
改为:
view plain
1. final FormField fieldOccu= dataForm.addField(); 2. fieldOccu.setVariable(\);
3. fieldOccu.setLabel(LocaleUtils.getLocalizedString(\)); 4. fieldOccu.addValue(Integer.toString(room.getOccupantsCount()));
正在阅读:
xmpp-多人聊天实例04-13
新人教版八年级数学上《轴对称》全章导学案05-02
医院增收节支方案01-26
尔雅通识课大学生爱情兵法章节测试题05-06
高新区2010-2011学年度第二学期期终试卷 八年级数学03-29
寒冷的雨夜作文600字06-16
加减乘除都是爱读后感精选10篇12-12
16秋福师《现代语言学》在线作业一09-21
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 实例
- 多人
- 聊天
- xmpp
- 小学科学教师招聘考试试题及答案
- 小型教育网站的开发与建设
- 2018年中国雾霾治理行业分析与市场报告目录
- 旅行社规章制度
- 第四野战军 战斗序列
- 一次函数(知识点+题型)
- 10.哈尔滨学院本科毕业论文(设计)文本编辑规范
- 正弦波三相变频电源的设计
- 管理技术职位分析解析调查问卷(样板) - 图文
- 西南政法大学全日制研究生学业奖学金实施办法(试行)
- 胜利石油管理局计量器具管理制度
- 语文教学:2015年高考诗歌鉴赏 - 鉴赏事物形象导学案
- Unit 8Unit 8 Have you read Treasure Island yet 单元测试题 2
- 桐庐县百江镇委员会桐庐县百江镇人民政府
- 毛概论文
- 第一轮复习自己整理绝对经典2016二项式定理--第一轮
- 操作系统复习题2016
- 微机原理试题作业2(答案)
- 八年级秋四科联赛数学试卷
- 机动车检测站应急预案