从: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包里面含有发送离线消息、文件等类

以下是创建一个连接

  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中设置

发送消息

  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. }

发送离线消息

  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. }

得到好友列表

  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. }

管理好友,监听好友请求

  1. <pre name="code" class="java">
  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类的使用

  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. }

设置自己的状态信息

  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. }

监听好友的状态

  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. }

监听好友的输入状态

  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. }

增加聊天室进行多人聊天

  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. }

发送和接收文件

  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. }

创建多人聊天室

  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. }

管理房间

  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. }

注冊

  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

  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. android-使用环信SDK开发即时通信功能及源代码下载

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

  2. (转)基于即时通信和LBS技术的位置感知服务(三):搭建Openfire服务器+测试2款IM客户端

    主要包含4个章节: 1. Java 领域的即时通信的解决方案 2. 搭建 Openfire 服务器 3. 使用客户端测试我们搭建的 Openfire 服务器 4. Smack 和 ASmack 一.J ...

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

    你看今天是(三)对吧,前面肯定有(一)和(二),在发表完iOS开发之使用XMPPFramework实现即时通信(一)和iOS开发之使用XMPPFramework实现即时通信(二)后有好多的小伙伴加我Q ...

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

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

  5. 【原】iOS学习42即时通信之XMPP(1)

    1. 即时通信 1> 概述 即时通讯(Instant Messaging)是目前Internet上最为流行的通讯方式,各种各样的即时通讯软件也层出不穷,服务提供商也提供了越来越丰富的通讯服务功能 ...

  6. iOS开发-即时通信XMPP

    1. 即时通信 1> 概述 即时通讯(Instant Messaging)是目前Internet上最为流行的通讯方式,各种各样的即时通讯软件也层出不穷,服务提供商也提供了越来越丰富的通讯服务功能 ...

  7. 基于XMPP协议的Android即时通信系

    以前做过一个基于XMPP协议的聊天社交软件,总结了一下.发出来. 设计基于开源的XMPP即时通信协议,采用C/S体系结构,通过GPRS无线网络用TCP协议连接到服务器,以架设开源的Openfn'e服务 ...

  8. 【原】iOS学习43即时通信之XMPP(2)

    本篇是 即时通信之XMPP(2) 接上次 即时通信之XMPP(1) 1. 好友列表 1> 初始化好友花名册 // 获取管理好友的单例对象 XMPPRosterCoreDataStorage *r ...

  9. (转)基于即时通信和LBS技术的位置感知服务(二):XMPP协议总结以及开源解决方案

    在<基于即时通信和LBS技术的位置感知服务(一):提出问题及解决方案>一文中,提到尝试使用XMPP协议来实现即时通信.本文将对XMPP协议框架以及相关的C/S架构进行介绍,协议的底层实现不 ...

随机推荐

  1. URAL1523(dp+树状数组)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=41224#problem/B 分析:可以设dp[i][j]表示以i结尾长度为j的 ...

  2. Xenu-web开发死链接检測工具应用

    Xenu 是一款深受业界好评,并被广泛使用的死链接检測工具. 时常检測站点并排除死链接,对站点的SEO 很重要,由于大量死链接存在会减少用户和搜索引擎对站点的信任,web程序开发者还可通过其找到死链接 ...

  3. VC++ 在两个文件互相包含时会出现的错误

    首先,要分别在两个文件中实现以下两个类 class Object { public: NewType ToType(); }; class NewType : public Object { } -- ...

  4. OpenCV 编程简单介绍(矩阵/图像/视频的基本读写操作)

    PS. 因为csdn博客文章长度有限制,本文有部分内容被截掉了.在OpenCV中文站点的wiki上有可读性更好.而且是完整的版本号,欢迎浏览. OpenCV Wiki :<OpenCV 编程简单 ...

  5. 大规模集群管理工具Borg

    Google的大规模集群管理工具Borg 概述 Google的Borg系统是一个集群管理工具,在它上面运行着成千上万的job,这些job来自许许多多不同的应用,并且跨越多个集群,而每个集群又由大量的机 ...

  6. php如何判断用户是从指定页面跳转进来的

    $_SERVER['HTTP_REFERER']下'HTTP_REFERER' 引导用户代理到当前页的前一页的地址(如果存在).由 user agent 设置决定.并不是所有的用户代理都会设置该项,有 ...

  7. Linux内核的同步机制---自旋锁

    自旋锁的思考:http://bbs.chinaunix.net/thread-2333160-1-1.html 近期在看宋宝华的<设备驱动开发具体解释>第二版.看到自旋锁的部分,有些疑惑. ...

  8. windows phone (14) 简单了解Ellipse元素和Rectangle元素

    原文:windows phone (14) 简单了解Ellipse元素和Rectangle元素  System.Windows.Shapes命名空间中包含了显示矢量图形的元素分别为ellipse和re ...

  9. 阶乘因式分解(一)(南阳oj56)

    阶乘因式分解(一) 时间限制:3000 ms  |  内存限制:65535 KB 难度:2 描写叙述 给定两个数m,n,当中m是一个素数. 将n(0<=n<=10000)的阶乘分解质因数, ...

  10. 【原创】leetCodeOj --- Factorial Trailing Zeroes 解题报告

    原题地址: https://oj.leetcode.com/problems/factorial-trailing-zeroes/ 题目内容: Given an integer n, return t ...