从:http://blog.csdn.net/casuallc/article/details/34794501

server:openfire

client计划:smark写

首先安装openfire,下载client直接安装就可以。数据库能够用openfire自身的,也能够用自己的数据库,仅仅要按提示设置好參数就可以

之后,就能够用smark写一个client測试与openfire的通信了(须要引进的jar包除了smark自身的。还要引入xmlpull-1.1.3.1.jar、kxml2-2.3.0.jar两个包

,作用是解析xml文件)

备注:我用的smark版本号是4.0。要引入的基本包有smack-core-4.0.0.jar、smack-debug-4.0.0.jar、smack-extensions-4.0.0.jar、smack-tcp-4.0.0.jar

debug包使用来调试的。tcp是用来初始化连接的、extension包里面含有发送离线消息、文件等类

以下是创建一个连接

[java] view plaincopy
  1. ConnectionConfiguration config = new ConnectionConfiguration("ip", 5222);
  2. //设置成disabled。则不会去验证server证书是否有效,默觉得enabled
  3. config.setSecurityMode(SecurityMode.disabled);
  4. //设置能够调试。默觉得false,老版本号的写法为XMPPConnection.DEBUG_ENABLED = true;
  5. config.setDebuggerEnabled(true);
  6. //设置是否在登陆的时候告诉server,默觉得true
  7. config.setSendPresence(false);
  8. //XMPPConnection在后来的版本号中改成了抽象类
  9. XMPPConnection conn = new XMPPTCPConnection(config);
  10. //设置等待时间
  11. conn.setPacketReplyTimeout(5000);
  12. conn.connect();
  13. //username,password,资源名(比如:假设是用潘迪安发送的消息。则资源名就是:  潘迪安,用于标识client)
  14. conn.login("admin", "0", "资源名");

关于连接的參数,在新版本号中所有在config中设置

发送消息

[html] view plaincopy
  1. private void testSendMessage(XMPPConnection conn) throws Exception {
  2. //jid在数据表中ofroster能够查到。通常是   username@server名称
  3. Chat chat = ChatManager.getInstanceFor(conn).createChat("ly@192.168.1.100", new MessageListener() {
  4. @Override
  5. public void processMessage(Chat chat, Message message) {
  6. System.out.println("Received message: " + message);
  7. }
  8. });
  9. Message msg = new Message();
  10. msg.setBody("hello world");
  11. //定义成normal,在对象不在线时发送离线消息。消息存放在数据表ofoffline中
  12. msg.setType(Message.Type.normal);
  13. //发送消息。參数能够是字符串,也能够是message对象
  14. chat.sendMessage(msg);
  15. //发送广播
  16. conn.sendPacket(msg);
  17. }

发送离线消息

[java] view plaincopy
  1. private void testOffLine(XMPPConnection conn) throws Exception {
  2. //离线文件
  3. OfflineMessageManager offMM = new OfflineMessageManager(conn);
  4. System.out.println("离线文件数量 :" + offMM.getMessageCount());
  5. System.out.println("离线文件内容 :");
  6. //经測试。当调用getMessages时,会触发chat设置的监听器,从而输出离线消息内容。可是getMessages方法返回的离线消息为空
  7. //推測回调函数的触发条件是一个变量,方变量改变时(while(flag))。运行回调函数
  8. List<Message> listMessage = offMM.getMessages();
  9. //listMessage的大小为0
  10. System.out.println(listMessage.size());
  11. for(Message m : offMM.getMessages()) {
  12. System.out.println(" 离线  : " + m.getBody() + m.getBodies());
  13. }
  14. }

得到好友列表

[java] view plaincopy
  1. private void testGetRoster(XMPPConnection conn) throws Exception {
  2. //得到该user的roster(相当于好友列表),不区分是否在线
  3. Roster r = conn.getRoster();
  4. Collection<RosterEntry> c = r.getEntries();
  5. for(RosterEntry re : c) {
  6. StringBuilder sb = new StringBuilder();
  7. sb.append("name : ").append(re.getName());
  8. sb.append("\nuser : ").append(re.getUser());
  9. sb.append("\ntype : ").append(re.getType());
  10. sb.append("\nstatus : ").append(re.getStatus());
  11. System.out.println(sb.toString());
  12. System.out.println("-----------------------------");
  13. }
  14. System.out.println(r.getEntries());
  15. //输出内容
  16. /*  name : null
  17. user : ly@192.168.1.100
  18. type : from
  19. status : null
  20. -----------------------------
  21. name : null
  22. user : yy@192.168.1.100
  23. type : to
  24. status : null
  25. -----------------------------
  26. [ly@192.168.1.100, yy@192.168.1.100]
  27. */
  28. }

管理好友,监听好友请求

[java] view plaincopy
  1. <pre name="code" class="java">
[java] view plaincopy
  1. </pre><pre name="code" class="java">private void testAddAndDelFriends(final XMPPConnection conn) throws Exception {
  2. Roster r = conn.getRoster();
  3. // 用户的jid。昵称,用户的分组。假设该用户不存在也能够加入
  4. //  r.createEntry("yy@192.168.1.100", "yy", null);
  5. // rosterEntry的构造方法是包訪问权限。不能直接new
  6. //  RosterEntry entry = r.getEntry("ly@192.168.1.100");
  7. // r.removeEntry(entry);
  8. //监听全部的请求,之后能够过滤掉不想要的请求
  9. PacketListener packetListener = new PacketListener() {
  10. @Override
  11. public void processPacket(Packet packet) throws NotConnectedException {
  12. /*
  13. available
  14. unavailable
  15. subscribe  发出加入好友的请求
  16. subscribed 允许加入好友
  17. unsubscribe 发出删除好友请求
  18. unsubscribed 删除好友(即拒绝加入好友)。
  19. 备注:对方发出加入好友的请求后。在server端会自己主动把对方加入到自己的roster,所以在运行处理好友请求或加入删除好友的时候,要又一次获取roster,更新好友列表
  20. */
  21. Presence presence = (Presence) packet;
  22. Type type = presence.getType();
  23. //请求加入好友
  24. if(Type.subscribe.equals(type)) {
  25. //注意点:要设置to(即指明要发送的对象,否则不能成功拒绝),至于from不用设置,由于在sendPacket方法中已经设置了,formMode初始化的时候为OMITTED,能够自己设置
  26. /*
  27. switch (fromMode) {
  28. case OMITTED:
  29. packet.setFrom(null);
  30. break;
  31. case USER:
  32. packet.setFrom(getUser());//getUser是抽象方法
  33. break;
  34. */
  35. //直接用传来的presence,不能自己新建一个presence(可能要验证presence是否是原来的对象,来推断是谁拒绝了谁的好友请求),否则不能成功拒绝对方加入好友
  36. //例:A--presence1-->B   A---presence2---C, C---presence3---A这样server就没办法推断是B、C中的哪一个拒绝了A的请求
  37. presence.setType(Type.unsubscribed);//拒绝,发送了一条presence
  38. //presence.setType(Type.unavailable);//发送了两条presence,一条是subscribed,一条是unavailabled,能接受对方消息,自己的状态显示隐身。再一次登录的时候显示在线
  39. presence.setTo(presence.getFrom());
  40. presence.setPacketID(presence.getPacketID());
  41. Roster r = conn.getRoster();
  42. try {
  43. RosterEntry entry = r.getEntry(presence.getFrom());
  44. if(entry != null)
  45. r.removeEntry(entry);
  46. } catch (NotLoggedInException | NoResponseException | XMPPErrorException e) {
  47. // TODO Auto-generated catch block
  48. e.printStackTrace();
  49. }
  50. conn.sendPacket(presence);
  51. //多方删除自己
  52. } else if(Type.unsubscribe.equals(type)) {
  53. presence.setTo(presence.getFrom());
  54. presence.setType(Type.unsubscribe);
  55. Roster r = conn.getRoster();
  56. try {
  57. r.removeEntry(r.getEntry(presence.getFrom()));
  58. } catch (NotLoggedInException | NoResponseException | XMPPErrorException e) {
  59. // TODO Auto-generated catch block
  60. e.printStackTrace();
  61. }
  62. conn.sendPacket(presence);
  63. }
  64. }
  65. };
  66. //      PacketFilter packetFilter = new PacketFilter() {
  67. //
  68. //          //假设返回false,则不把事件交给listener处理,否则会调用packetListener中的processPacket方法
  69. //          //方法解释true if and only if packet passes the filter.
  70. //          @Override
  71. //          public boolean accept(Packet packet) {
  72. //              System.out.println("2" + packet);
  73. //              return true;
  74. //          }
  75. //      };
  76. //过滤掉全部的不是好友请求、删除的全部packet
  77. PacketFilter packetFilter = new AndFilter(new PacketTypeFilter(Presence.class));
  78. conn.addPacketListener(packetListener, packetFilter);
  79. //未知
  80. RosterExchangeManager rem = new RosterExchangeManager(conn);
  81. rem.addRosterListener(new RosterExchangeListener() {
  82. @Override
  83. public void entriesReceived(String from, Iterator<RemoteRosterEntry> remoteRosterEntries) {
  84. System.out.println(from);
  85. while(remoteRosterEntries.hasNext()) {
  86. RemoteRosterEntry entry = remoteRosterEntries.next();
  87. System.out.println(entry.getUser() + " : " + entry.getName());
  88. }
  89. }
  90. });
  91. }

得到好友的信息。主要是VCard类的使用

[java] view plaincopy
  1. private void testGetFriendInfo(XMPPConnection conn) throws Exception {
  2. VCard vCard = new VCard();
  3. VCardManager vcManager = new VCardManager();
  4. //此处返回false
  5. boolean b = vcManager.isSupported("ly@192.168.1.100", conn);
  6. System.out.println(b);
  7. vCard.load(conn, "ly@192.168.1.100");
  8. // Load Avatar from VCard
  9. byte[] avatarBytes = vCard.getAvatar();
  10. //得不到头像等的信息
  11. if(avatarBytes == null) {
  12. return;
  13. }
  14. // To create an ImageIcon for Swing applications
  15. ImageIcon icon = new ImageIcon(avatarBytes);
  16. System.out.println(icon.getIconWidth() + " : " + icon.getIconHeight());
  17. // To create just an image object from the bytes
  18. ByteArrayInputStream bais = new ByteArrayInputStream(avatarBytes);
  19. try {
  20. Image image = ImageIO.read(bais);
  21. FileOutputStream fos = new FileOutputStream("D://icon.jpg");
  22. fos.write(avatarBytes);
  23. fos.close();
  24. }
  25. catch (IOException e) {
  26. e.printStackTrace();
  27. }
  28. }

设置自己的状态信息

[java] view plaincopy
  1. private void testSetInfo(XMPPConnection conn) throws Exception {
  2. VCard vCard = new VCard();
  3. vCard.load(conn);
  4. vCard.setEmailHome("admin@126.com");
  5. vCard.setAddressFieldWork("POSTAL", "汇宝大厦");
  6. //改动完要保存改动的内容,否则没办法更新到server
  7. vCard.save(conn);
  8. //改动自身的状态,包含隐身,上线(能够指定对特定的好友更改状态)
  9. Presence p = new Presence(Type.available);
  10. p.setTo("ly@192.168.1.100");
  11. //改动心情
  12. p.setStatus("我的心情");
  13. //相同要发到server
  14. conn.sendPacket(p);
  15. }

监听好友的状态

[java] view plaincopy
  1. private void testSetRosterListener(XMPPConnection conn) throws Exception {
  2. Roster r = conn.getRoster();
  3. r.createEntry("ly@192.168.1.100", "昵称", null);
  4. r.addRosterListener(new RosterListener() {
  5. @Override
  6. public void presenceChanged(Presence presence) {
  7. //更改状态信息时调用该方法(更改在线状态。改动心情。改动头像等)
  8. System.out.println("presenceChanged");
  9. }
  10. @Override
  11. public void entriesUpdated(Collection<String> addresses) {
  12. //该方法以及以下的方法都是在server改动好友信息时触发
  13. System.out.println("entriesUpdated");
  14. }
  15. @Override
  16. public void entriesDeleted(Collection<String> addresses) {
  17. // TODO Auto-generated method stub
  18. System.out.println("entriesDeleted");
  19. }
  20. @Override
  21. public void entriesAdded(Collection<String> addresses) {
  22. // TODO Auto-generated method stub
  23. System.out.println("entriesAdded");
  24. }
  25. });
  26. }

监听好友的输入状态

[java] view plaincopy
  1. private void testGetExtention(XMPPConnection conn) throws Exception {
  2. Chat chat = ChatManager.getInstanceFor(conn).createChat("ly@192.168.1.100", new MessageListener() {
  3. @Override
  4. public void processMessage(Chat chat, Message message) {
  5. //得到输入状态,分为五种:正在输入(composing)。暂停输入(paused),发送(active),关闭对话框(gone)
  6. PacketExtension pe = message.getExtension("http://jabber.org/protocol/chatstates");
  7. switch (pe.getElementName()) {
  8. case "composing":
  9. System.out.println("正在输入......");
  10. break;
  11. case "paused":
  12. System.out.println("正在冥想......");
  13. break;
  14. case "active":
  15. System.out.println("对方已发送。");
  16. break;
  17. case "gone":
  18. System.out.println("对话框已被关闭。");
  19. break;
  20. default:
  21. break;
  22. }
  23. }
  24. });
  25. Message msg = new Message();
  26. msg.addExtension(new ChatStateExtension(ChatState.gone));
  27. msg.setBody("hello world");
  28. chat.sendMessage(msg);
  29. }

增加聊天室进行多人聊天

[java] view plaincopy
  1. private MultiUserChat multiUserChat;
  2. private void testMutiUserChat(XMPPConnection conn) throws Exception {
  3. MultiUserChat.addInvitationListener(conn, new InvitationListener() {
  4. @Override
  5. public void invitationReceived(XMPPConnection conn, String room, String inviter, String reason, String password, Message message) {
  6. StringBuilder sb = new StringBuilder();
  7. sb.append("房间号  : ").append(room);
  8. sb.append("\n邀请者  : ").append(inviter);
  9. sb.append("\n理由  : ").append(reason);
  10. sb.append("\n密码  : ").append(password);
  11. sb.append("\n消息  : ").append(message);
  12. System.out.println(sb);
  13. multiUserChat = new MultiUserChat(conn, room);
  14. try {
  15. multiUserChat.join("admin", password);
  16. } catch (XMPPErrorException e) {
  17. // TODO Auto-generated catch block
  18. e.printStackTrace();
  19. } catch (SmackException e) {
  20. // TODO Auto-generated catch block
  21. e.printStackTrace();
  22. }
  23. multiUserChat.addMessageListener(new PacketListener() {
  24. @Override
  25. public void processPacket(Packet packet) throws NotConnectedException {
  26. Message msg = (Message) packet;
  27. System.out.println(msg.getBody());
  28. }
  29. });
  30. }
  31. });
  32. while(true) {
  33. try {
  34. Thread.sleep(500);
  35. if(multiUserChat == null)
  36. continue;
  37. //关于发送消息的问题。能够直接发字符串
  38. //也能够发送message。可是要设定message的一些參数,否则不能发送(參数设置例如以下)
  39. //用Chat发送消息时。不用设置,原因是在Chat的sendMessage方法中已经加入了这些參数
  40. /*
  41. *  message.setTo(participant);
  42. message.setType(Message.Type.chat);
  43. message.setThread(threadID);
  44. */
  45. //可是,用MultiUserChat类中的sendMessage方法,直接调用了XMPPConnection中的sendPacket方法,没有设置Message的參数
  46. Message msg = new Message();
  47. //房间名称
  48. msg.setTo("a@conference.192.168.1.100");
  49. msg.setType(Message.Type.groupchat);
  50. msg.setThread(Thread.currentThread().getId() + "");
  51. msg.setBody("hello");
  52. multiUserChat.sendMessage(msg);
  53. break;
  54. } catch (InterruptedException e) {
  55. e.printStackTrace();
  56. } catch (NotConnectedException e) {
  57. e.printStackTrace();
  58. } catch (XMPPException e) {
  59. e.printStackTrace();
  60. }
  61. }
  62. }

发送和接收文件

[java] view plaincopy
  1. private void testSendFile(XMPPConnection conn) throws Exception {
  2. // 发送文件的管理器
  3. FileTransferManager ftm = new FileTransferManager(conn);
  4. ftm.addFileTransferListener(new FileTransferListener() {
  5. @Override
  6. public void fileTransferRequest(FileTransferRequest request) {
  7. System.out.println(request.getFileName());
  8. IncomingFileTransfer inComingFileTransfer = request.accept();
  9. try {
  10. //能够直接写到file文件里
  11. File file = new File("D://" + request.getFileName());
  12. inComingFileTransfer.recieveFile(file);
  13. } catch (Exception e) {
  14. e.printStackTrace();
  15. }
  16. }
  17. });
  18. // 注意jid格式。以下为标准格式,假设不正确则会抛出jid格式错误的异常
  19. // (if (parseName(jid).length() <= 0 || parseServer(jid).length() <= 0|| parseResource(jid).length() <= 0) {
  20. // return false;
  21. OutgoingFileTransfer oft = ftm.createOutgoingFileTransfer("admin@192.168.1.100/潘迪安");
  22. File file = new File("D://time.jpg");
  23. oft.sendFile(file, "图片");
  24. System.out.println(oft.isDone());
  25. }

创建多人聊天室

[java] view plaincopy
  1. private void testCreateRoom(XMPPConnection conn) throws Exception {
  2. while(true) {
  3. if(conn != null)
  4. break;
  5. }
  6. //@之前的是会议房间名称。之后的是conference+ip(固定格式,不能改变)
  7. MultiUserChat muc = new MultiUserChat(conn, "ly@conference.192.168.1.100");
  8. //昵称,假设该房间已经存在,则会抛出Creation failed - Missing acknowledge of room creation.(先增加房间,然后离开房间)
  9. muc.create("real_admin");
  10. Form form = muc.getConfigurationForm();
  11. Form submitForm = form.createAnswerForm();
  12. //以下的初始化有什么用,在创建submitForm的时候已经设置參数了
  13. //      List<FormField> list = submitForm.getFields();
  14. //      for(FormField f : list) {
  15. //          if(!(FormField.TYPE_HIDDEN.equals(f.getType())) && f.getVariable() != null) {
  16. //              submitForm.setDefaultAnswer(f.getVariable());
  17. //          }
  18. //      }
  19. //參数究竟是什么意思。为什么有的能够设置,有的不能够设置
  20. /*
  21. *  variable:FORM_TYPE  type:hidden  value:[http://jabber.org/protocol/muc#roomconfig]
  22. variable:muc#roomconfig_roomname  type:text-single  value:[]
  23. variable:muc#roomconfig_roomdesc  type:text-single  value:[]
  24. variable:muc#roomconfig_changesubject  type:boolean  value:[]
  25. variable:muc#roomconfig_maxusers  type:list-single  value:[]
  26. variable:muc#roomconfig_presencebroadcast  type:list-multi  value:[]
  27. variable:muc#roomconfig_publicroom  type:boolean  value:[]
  28. variable:muc#roomconfig_persistentroom  type:boolean  value:[]
  29. variable:muc#roomconfig_moderatedroom  type:boolean  value:[]
  30. variable:muc#roomconfig_membersonly  type:boolean  value:[]
  31. variable:muc#roomconfig_allowinvites  type:boolean  value:[]
  32. variable:muc#roomconfig_passwordprotectedroom  type:boolean  value:[]
  33. variable:muc#roomconfig_roomsecret  type:text-private  value:[]
  34. variable:muc#roomconfig_whois  type:list-single  value:[]
  35. variable:muc#roomconfig_enablelogging  type:boolean  value:[]
  36. variable:x-muc#roomconfig_reservednick  type:boolean  value:[]
  37. variable:x-muc#roomconfig_canchangenick  type:boolean  value:[]
  38. variable:x-muc#roomconfig_registration  type:boolean  value:[]
  39. variable:muc#roomconfig_roomadmins  type:jid-multi  value:[]
  40. variable:muc#roomconfig_roomowners  type:jid-multi  value:[]
  41. */
  42. //submitForm.setAnswer(FormField.TYPE_TEXT_PRIVATE, "0");
  43. muc.sendConfigurationForm(submitForm);
  44. //被拒绝时运行
  45. muc.addInvitationRejectionListener(new InvitationRejectionListener() {
  46. @Override
  47. public void invitationDeclined(String invitee, String reason) {
  48. System.out.println(invitee + " : " + reason);
  49. }
  50. });
  51. muc.invite("yy@192.168.1.100", "ly_room");
  52. }

管理房间

[java] view plaincopy
  1. <pre name="code" class="java">private void testManageRoom(XMPPConnection conn) throws Exception {
  2. testCreateRoom(conn);
  3. MultiUserChat muc = new MultiUserChat(conn, "ly@conference.192.168.1.100");
  4. //Thread.sleep(5000);
  5. //赋予管理员权限
  6. //muc.grantAdmin("yy@192.168.1.100");
  7. //Thread.sleep(5000);
  8. //假设是管理员,则不能踢除
  9. //muc.banUser("yy@192.168.1.100", "太水");
  10. //收回说话的权限
  11. muc.revokeVoice("yy");
  12. //muc.grantVoice("yy");
  13. }

注冊

[java] view plaincopy
  1. private void testRegister(XMPPConnection conn) throws Exception {
  2. //能够直接改登陆用户的信息(假设是username的值必须和该用户的用户名同样)
  3. Registration r = new Registration();
  4. Map<String, String> attributes = new HashMap<String, String>();
  5. attributes.put("username", "newuser");
  6. attributes.put("password", "0");
  7. attributes.put("email", "new00@126.com");
  8. attributes.put("name", "name@192.168.1.100");
  9. //加入用户,要设置type类型为set。原因不明
  10. r.setType(IQ.Type.SET);
  11. r.setAttributes(attributes);
  12. //过滤器,用来过滤由server返回的信息(即得到注冊信息的内容)
  13. PacketFilter packetFilter = new AndFilter(new PacketIDFilter(r.getPacketID()), new PacketTypeFilter(IQ.class));
  14. PacketCollector collector = conn.createPacketCollector(packetFilter);
  15. System.out.println(r);
  16. conn.sendPacket(r);
  17. IQ result = (IQ) collector.nextResult();
  18. if(result == null) {
  19. System.out.println("server没有返回不论什么信息");
  20. } else {
  21. switch (result.getType().toString()) {
  22. case "result":
  23. System.out.println("注冊成功");
  24. break;
  25. case "error":
  26. if(result.getError().toString().equalsIgnoreCase("conflict"))
  27. System.out.println("用户名称已存在");
  28. else
  29. System.out.println("注冊失败");
  30. break;
  31. default:
  32. break;
  33. }
  34. }
  35. }

管理账号password

[java] view plaincopy
  1. private void testModifyPwd(XMPPConnection conn) throws Exception {
  2. //创建一个用户信息管理,能够创建新用户。或者改动用户密码
  3. AccountManager am = AccountManager.getInstance(conn);
  4. Collection<String> c = am.getAccountAttributes();
  5. for(String s : c) {
  6. System.out.println(s);
  7. }
  8. /*
  9. * 通过accountManager能够得到的属性
  10. *  username
  11. email
  12. registered
  13. name
  14. password
  15. */
  16. am.getAccountAttribute("username");
  17. am.createAccount("newUser", "0");
  18. am.changePassword("00");
  19. }

至于细节,中遇到,我在程序代码描述

参考博客:

http://blog.csdn.net/shimiso/article/details/11225873

smark和openfire即时通信代码相关推荐

  1. 对方正在输入 java_smark和openfire即时通信代码

    出自:http://blog.csdn.net/casuallc/article/details/34794501 服务器:openfire 客户端程序:smark编写 首先安装openfire,下载 ...

  2. android-使用环信SDK开发即时通信功能及源码下载

    最近项目中集成即时聊天功能,挑来拣去,最终选择环信SDK来进行开发,选择环信的主要原因是接口方便.简洁,说明文档清晰易懂.文档有android.ios.和后台服务器端,还是非常全的. 环信官网:htt ...

  3. 利用openfire和smark的即时通信

    利用openfire和smark的即时通信 2014-06-26 09:12 3240人阅读 评论(5) 收藏 举报  分类: Android(3)  版权声明:本文为博主原创文章,未经博主允许不得转 ...

  4. java即时通信解决方案openfire+spark完整安装指南

    本文介绍基于java的即时通信解决方案openfire3.6.4+spark2.5.8的完整的安装说明,并介绍了使用smack的java类库如何与im用户交互的例子,这样使得业务系统的消息可以通过sm ...

  5. 【即时通信】openfire安装和配置讲解

    文章目录 概述 一.下载openfire,解压就可以openfire启动服务.这里我安装openfire在linux服务器上.服务器地址:10.119.9.149. 二.准备openfire所需的数据 ...

  6. iOS开发之使用XMPPFramework实现即时通信(二)

    上篇的博客iOS开发之使用XMPPFramework实现即时通信(一)只是本篇的引子,本篇博客就给之前的微信加上即时通讯的功能,主要是对XMPPFramework的使用.本篇博客中用到了Spark做测 ...

  7. agsXMPP + Openfire 即时通讯开发(二) 【文件传输】

    上篇bolg(agsXMPP + Openfire 即时通讯开发(一) [agsXMPP 连接 Openfire])中agsXMPP的MiniClient已经可以相互之间进行通讯了,本篇介绍如何进行文 ...

  8. 基于android即时通信聊天系统

    本即时通讯毕业设计主要采用Java后台以及手机端app的体系结构,建立了关于XMPP协议的安卓app即时通信系统,本系统包含了客户端以及服务端,(即前台后台)服务器是使用OpenFire.是一个jav ...

  9. xmpp协议(即时通信协议规范)

    转载自 https://www.cnblogs.com/jiyuqi/p/5085932.html 相关背景 IM(Instant Messaging)正在被广泛使用,特别是公司与它们的客户互动连接方 ...

最新文章

  1. 如何测量智能产品的AI智商水平,论AI的三种智商 |未来研究
  2. Paramiko: SSH and SFTP With Python
  3. Asp.net Core认证和授权:JWT认证和授权
  4. nginx 卸载后重新安装/etc/nginx配置文件没了,cannot open /etc/nginx/nginx.conf (No such file or directory)...
  5. C++lowest common ancestor最近公共祖先算法(附完整源码)
  6. 第三次学JAVA再学不好就吃翔(part80)--List三个子类的特点
  7. HTML5 API详解(11):Cache 应用程序缓存,这下离线也可以玩了
  8. fir.im同款企业级APP分发平台系统源码
  9. 触摸事件touchevent
  10. jetbrains IDEA/pycharm修改代码提示框配色
  11. C51单片机————串行接口
  12. HDU-1255 覆盖的面积 矩形面积交
  13. RHEL5_x64上安装oracle 11.2
  14. tcgames使用有延迟_心得分享:tcgames电脑玩刺激战场怎么用最流畅?
  15. NB-IoT未来发展,主要是靠什么驱动的?
  16. 贴片二极管正负极如何区分
  17. yarn的安装及使用教程
  18. 对称算法与非对称算法
  19. 滑铁卢大学开发了一套AI工具,教泥瓦匠初学者搬砖诀窍
  20. jqGrid参数整理

热门文章

  1. python 替换空格
  2. linux内核的中断上下文,Linux操作系统中中断上下文中的互斥
  3. uml 时序图_UML学习-14种UML图
  4. 恢复错误:\anaconda3\lib\site-packages\zmq\backend\cffi\__pycache__\_cffi_ext.c(266)
  5. 32位程序调用64位dll_电脑系统怎样区分32位和64位
  6. 通过python里面的pyautogui自动化控制鼠标和键盘操作
  7. python抽奖游戏大全_抽奖游戏
  8. 《STL源码剖析》学习--6章--_rotate算法分析
  9. VideoCapture类
  10. 【多线程】C++11进行多线程开发 (std::thread)