首页 > 代码库 > smark和openfire即时通信代码
smark和openfire即时通信代码
出自:http://blog.csdn.net/casuallc/article/details/34794501
服务器:openfire
客户端程序:smark编写
首先安装openfire,下载客户端后直接安装即可,数据库可以用openfire自身的,也可以用自己的数据库,只要按提示设置好参数即可
之后,就可以用smark写一个客户端测试与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
- ConnectionConfiguration config = new ConnectionConfiguration("ip", 5222);
- //设置成disabled,则不会去验证服务器证书是否有效,默认为enabled
- config.setSecurityMode(SecurityMode.disabled);
- //设置可以调试,默认为false,老版本的写法为XMPPConnection.DEBUG_ENABLED = true;
- config.setDebuggerEnabled(true);
- //设置是否在登陆的时候告诉服务器,默认为true
- config.setSendPresence(false);
- //XMPPConnection在后来的版本中改成了抽象类
- XMPPConnection conn = new XMPPTCPConnection(config);
- //设置等待时间
- conn.setPacketReplyTimeout(5000);
- conn.connect();
- //用户名,密码,资源名(例如:如果是用潘迪安发送的消息,则资源名就是: 潘迪安,用于标识客户端)
- conn.login("admin", "0", "资源名");
发送消息
[html] view plaincopy
- private void testSendMessage(XMPPConnection conn) throws Exception {
- //jid在数据表中ofroster可以查到,一般是 用户名@服务器名称
- Chat chat = ChatManager.getInstanceFor(conn).createChat("ly@192.168.1.100", new MessageListener() {
- @Override
- public void processMessage(Chat chat, Message message) {
- System.out.println("Received message: " + message);
- }
- });
- Message msg = new Message();
- msg.setBody("hello world");
- //定义成normal,在对象不在线时发送离线消息,消息存放在数据表ofoffline中
- msg.setType(Message.Type.normal);
- //发送消息,参数可以是字符串,也可以是message对象
- chat.sendMessage(msg);
- //发送广播
- conn.sendPacket(msg);
- }
发送离线消息
[java] view plaincopy
- private void testOffLine(XMPPConnection conn) throws Exception {
- //离线文件
- OfflineMessageManager offMM = new OfflineMessageManager(conn);
- System.out.println("离线文件数量 :" + offMM.getMessageCount());
- System.out.println("离线文件内容 :");
- //经测试,当调用getMessages时,会触发chat设置的监听器,从而输出离线消息内容,但是getMessages方法返回的离线消息为空
- //猜测回调函数的触发条件是一个变量,方变量改变时(while(flag)),执行回调函数
- List<Message> listMessage = offMM.getMessages();
- //listMessage的大小为0
- System.out.println(listMessage.size());
- for(Message m : offMM.getMessages()) {
- System.out.println(" 离线 : " + m.getBody() + m.getBodies());
- }
- }
得到好友列表
[java] view plaincopy
- private void testGetRoster(XMPPConnection conn) throws Exception {
- //得到该user的roster(相当于好友列表),不区分是否在线
- Roster r = conn.getRoster();
- Collection<RosterEntry> c = r.getEntries();
- for(RosterEntry re : c) {
- StringBuilder sb = new StringBuilder();
- sb.append("name : ").append(re.getName());
- sb.append("\nuser : ").append(re.getUser());
- sb.append("\ntype : ").append(re.getType());
- sb.append("\nstatus : ").append(re.getStatus());
- System.out.println(sb.toString());
- System.out.println("-----------------------------");
- }
- System.out.println(r.getEntries());
- //输出内容
- /* name : null
- user : ly@192.168.1.100
- type : from
- status : null
- -----------------------------
- name : null
- user : yy@192.168.1.100
- type : to
- status : null
- -----------------------------
- [ly@192.168.1.100, yy@192.168.1.100]
- */
- }
管理好友,监听好友请求
[java] view plaincopy
- <pre name="code" class="java">
[java] view plaincopy
- </pre><pre name="code" class="java">private void testAddAndDelFriends(final XMPPConnection conn) throws Exception {
- Roster r = conn.getRoster();
- // 用户的jid,昵称,用户的分组。如果该用户不存在也可以添加
- // r.createEntry("yy@192.168.1.100", "yy", null);
- // rosterEntry的构造方法是包访问权限,不能直接new
- // RosterEntry entry = r.getEntry("ly@192.168.1.100");
- // r.removeEntry(entry);
- //监听所有的请求,之后可以过滤掉不想要的请求
- PacketListener packetListener = new PacketListener() {
- @Override
- public void processPacket(Packet packet) throws NotConnectedException {
- /*
- available
- unavailable
- subscribe 发出添加好友的请求
- subscribed 同意添加好友
- unsubscribe 发出删除好友请求
- unsubscribed 删除好友(即拒绝添加好友),
- 备注:对方发出添加好友的请求后,在服务器端会自动把对方加入到自己的roster,所以在执行处理好友请求或添加删除好友的时候,要重新获取roster,更新好友列表
- */
- Presence presence = (Presence) packet;
- Type type = presence.getType();
- //请求添加好友
- if(Type.subscribe.equals(type)) {
- //注意点:要设置to(即指明要发送的对象,否则不能成功拒绝),至于from不用设置,因为在sendPacket方法中已经设置了,formMode初始化的时候为OMITTED,可以自己设置
- /*
- switch (fromMode) {
- case OMITTED:
- packet.setFrom(null);
- break;
- case USER:
- packet.setFrom(getUser());//getUser是抽象方法
- break;
- */
- //直接用传来的presence,不能自己新建一个presence(可能要验证presence是否是原来的对象,来判断是谁拒绝了谁的好友请求),否则不能成功拒绝对方添加好友
- //例:A--presence1-->B A---presence2---C, C---presence3---A这样服务器就没办法判断是B、C中的哪一个拒绝了A的请求
- presence.setType(Type.unsubscribed);//拒绝,发送了一条presence
- //presence.setType(Type.unavailable);//发送了两条presence,一条是subscribed,一条是unavailabled,能接受对方消息,自己的状态显示隐身,再一次登录的时候显示在线
- presence.setTo(presence.getFrom());
- presence.setPacketID(presence.getPacketID());
- Roster r = conn.getRoster();
- try {
- RosterEntry entry = r.getEntry(presence.getFrom());
- if(entry != null)
- r.removeEntry(entry);
- } catch (NotLoggedInException | NoResponseException | XMPPErrorException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- conn.sendPacket(presence);
- //多方删除自己
- } else if(Type.unsubscribe.equals(type)) {
- presence.setTo(presence.getFrom());
- presence.setType(Type.unsubscribe);
- Roster r = conn.getRoster();
- try {
- r.removeEntry(r.getEntry(presence.getFrom()));
- } catch (NotLoggedInException | NoResponseException | XMPPErrorException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- conn.sendPacket(presence);
- }
- }
- };
- // PacketFilter packetFilter = new PacketFilter() {
- //
- // //如果返回false,则不把事件交给listener处理,否则会调用packetListener中的processPacket方法
- // //方法解释true if and only if packet passes the filter.
- // @Override
- // public boolean accept(Packet packet) {
- // System.out.println("2" + packet);
- // return true;
- // }
- // };
- //过滤掉所有的不是好友请求、删除的所有packet
- PacketFilter packetFilter = new AndFilter(new PacketTypeFilter(Presence.class));
- conn.addPacketListener(packetListener, packetFilter);
- //未知
- RosterExchangeManager rem = new RosterExchangeManager(conn);
- rem.addRosterListener(new RosterExchangeListener() {
- @Override
- public void entriesReceived(String from, Iterator<RemoteRosterEntry> remoteRosterEntries) {
- System.out.println(from);
- while(remoteRosterEntries.hasNext()) {
- RemoteRosterEntry entry = remoteRosterEntries.next();
- System.out.println(entry.getUser() + " : " + entry.getName());
- }
- }
- });
- }
得到好友的信息,主要是VCard类的使用
[java] view plaincopy
- private void testGetFriendInfo(XMPPConnection conn) throws Exception {
- VCard vCard = new VCard();
- VCardManager vcManager = new VCardManager();
- //此处返回false
- boolean b = vcManager.isSupported("ly@192.168.1.100", conn);
- System.out.println(b);
- vCard.load(conn, "ly@192.168.1.100");
- // Load Avatar from VCard
- byte[] avatarBytes = vCard.getAvatar();
- //得不到头像等的信息
- if(avatarBytes == null) {
- return;
- }
- // To create an ImageIcon for Swing applications
- ImageIcon icon = new ImageIcon(avatarBytes);
- System.out.println(icon.getIconWidth() + " : " + icon.getIconHeight());
- // To create just an image object from the bytes
- ByteArrayInputStream bais = new ByteArrayInputStream(avatarBytes);
- try {
- Image image = ImageIO.read(bais);
- FileOutputStream fos = new FileOutputStream("D://icon.jpg");
- fos.write(avatarBytes);
- fos.close();
- }
- catch (IOException e) {
- e.printStackTrace();
- }
- }
设置自己的状态信息
[java] view plaincopy
- private void testSetInfo(XMPPConnection conn) throws Exception {
- VCard vCard = new VCard();
- vCard.load(conn);
- vCard.setEmailHome("admin@126.com");
- vCard.setAddressFieldWork("POSTAL", "汇宝大厦");
- //修改完要保存修改的内容,否则没办法更新到服务器
- vCard.save(conn);
- //修改自身的状态,包括隐身,上线(可以指定对特定的好友更改状态)
- Presence p = new Presence(Type.available);
- p.setTo("ly@192.168.1.100");
- //修改心情
- p.setStatus("我的心情");
- //同样要发到服务器
- conn.sendPacket(p);
- }
监听好友的状态
[java] view plaincopy
- private void testSetRosterListener(XMPPConnection conn) throws Exception {
- Roster r = conn.getRoster();
- r.createEntry("ly@192.168.1.100", "昵称", null);
- r.addRosterListener(new RosterListener() {
- @Override
- public void presenceChanged(Presence presence) {
- //更改状态信息时调用该方法(更改在线状态,修改心情,修改头像等)
- System.out.println("presenceChanged");
- }
- @Override
- public void entriesUpdated(Collection<String> addresses) {
- //该方法以及下面的方法都是在服务器修改好友信息时触发
- System.out.println("entriesUpdated");
- }
- @Override
- public void entriesDeleted(Collection<String> addresses) {
- // TODO Auto-generated method stub
- System.out.println("entriesDeleted");
- }
- @Override
- public void entriesAdded(Collection<String> addresses) {
- // TODO Auto-generated method stub
- System.out.println("entriesAdded");
- }
- });
- }
监听好友的输入状态
[java] view plaincopy
- private void testGetExtention(XMPPConnection conn) throws Exception {
- Chat chat = ChatManager.getInstanceFor(conn).createChat("ly@192.168.1.100", new MessageListener() {
- @Override
- public void processMessage(Chat chat, Message message) {
- //得到输入状态,分为五种:正在输入(composing),暂停输入(paused),发送(active),关闭对话框(gone)
- PacketExtension pe = message.getExtension("http://jabber.org/protocol/chatstates");
- switch (pe.getElementName()) {
- case "composing":
- System.out.println("正在输入......");
- break;
- case "paused":
- System.out.println("正在冥想......");
- break;
- case "active":
- System.out.println("对方已发送。");
- break;
- case "gone":
- System.out.println("对话框已被关闭。");
- break;
- default:
- break;
- }
- }
- });
- Message msg = new Message();
- msg.addExtension(new ChatStateExtension(ChatState.gone));
- msg.setBody("hello world");
- chat.sendMessage(msg);
- }
加入聊天室进行多人聊天
[java] view plaincopy
- private MultiUserChat multiUserChat;
- private void testMutiUserChat(XMPPConnection conn) throws Exception {
- MultiUserChat.addInvitationListener(conn, new InvitationListener() {
- @Override
- public void invitationReceived(XMPPConnection conn, String room, String inviter, String reason, String password, Message message) {
- StringBuilder sb = new StringBuilder();
- sb.append("房间号 : ").append(room);
- sb.append("\n邀请者 : ").append(inviter);
- sb.append("\n理由 : ").append(reason);
- sb.append("\n密码 : ").append(password);
- sb.append("\n消息 : ").append(message);
- System.out.println(sb);
- multiUserChat = new MultiUserChat(conn, room);
- try {
- multiUserChat.join("admin", password);
- } catch (XMPPErrorException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (SmackException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- multiUserChat.addMessageListener(new PacketListener() {
- @Override
- public void processPacket(Packet packet) throws NotConnectedException {
- Message msg = (Message) packet;
- System.out.println(msg.getBody());
- }
- });
- }
- });
- while(true) {
- try {
- Thread.sleep(500);
- if(multiUserChat == null)
- continue;
- //关于发送消息的问题,可以直接发字符串
- //也可以发送message,但是要设定message的一些参数,否则不能发送(参数设置如下)
- //用Chat发送消息时,不用设置,原因是在Chat的sendMessage方法中已经添加了这些参数
- /*
- * message.setTo(participant);
- message.setType(Message.Type.chat);
- message.setThread(threadID);
- */
- //但是,用MultiUserChat类中的sendMessage方法,直接调用了XMPPConnection中的sendPacket方法,没有设置Message的参数
- Message msg = new Message();
- //房间名称
- msg.setTo("a@conference.192.168.1.100");
- msg.setType(Message.Type.groupchat);
- msg.setThread(Thread.currentThread().getId() + "");
- msg.setBody("hello");
- multiUserChat.sendMessage(msg);
- break;
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (NotConnectedException e) {
- e.printStackTrace();
- } catch (XMPPException e) {
- e.printStackTrace();
- }
- }
- }
发送和接收文件
[java] view plaincopy
- private void testSendFile(XMPPConnection conn) throws Exception {
- // 发送文件的管理器
- FileTransferManager ftm = new FileTransferManager(conn);
- ftm.addFileTransferListener(new FileTransferListener() {
- @Override
- public void fileTransferRequest(FileTransferRequest request) {
- System.out.println(request.getFileName());
- IncomingFileTransfer inComingFileTransfer = request.accept();
- try {
- //可以直接写到file文件中
- File file = new File("D://" + request.getFileName());
- inComingFileTransfer.recieveFile(file);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- });
- // 注意jid格式,下面为标准格式,如果不对则会抛出jid格式错误的异常
- // (if (parseName(jid).length() <= 0 || parseServer(jid).length() <= 0|| parseResource(jid).length() <= 0) {
- // return false;
- OutgoingFileTransfer oft = ftm.createOutgoingFileTransfer("admin@192.168.1.100/潘迪安");
- File file = new File("D://time.jpg");
- oft.sendFile(file, "图片");
- System.out.println(oft.isDone());
- }
[java] view plaincopy
- private void testCreateRoom(XMPPConnection conn) throws Exception {
- while(true) {
- if(conn != null)
- break;
- }
- //@之前的是会议房间名称,之后的是conference+ip(固定格式,不能改变)
- MultiUserChat muc = new MultiUserChat(conn, "ly@conference.192.168.1.100");
- //昵称,如果该房间已经存在,则会抛出Creation failed - Missing acknowledge of room creation.(先加入房间,然后离开房间)
- muc.create("real_admin");
- Form form = muc.getConfigurationForm();
- Form submitForm = form.createAnswerForm();
- //下面的初始化有什么用,在创建submitForm的时候已经设置参数了
- // List<FormField> list = submitForm.getFields();
- // for(FormField f : list) {
- // if(!(FormField.TYPE_HIDDEN.equals(f.getType())) && f.getVariable() != null) {
- // submitForm.setDefaultAnswer(f.getVariable());
- // }
- // }
- //参数到底是什么意思,为什么有的可以设置,有的不可以设置
- /*
- * variable:FORM_TYPE type:hidden value:[http://jabber.org/protocol/muc#roomconfig]
- variable:muc#roomconfig_roomname type:text-single value:[]
- variable:muc#roomconfig_roomdesc type:text-single value:[]
- variable:muc#roomconfig_changesubject type:boolean value:[]
- variable:muc#roomconfig_maxusers type:list-single value:[]
- variable:muc#roomconfig_presencebroadcast type:list-multi value:[]
- variable:muc#roomconfig_publicroom type:boolean value:[]
- variable:muc#roomconfig_persistentroom type:boolean value:[]
- variable:muc#roomconfig_moderatedroom type:boolean value:[]
- variable:muc#roomconfig_membersonly type:boolean value:[]
- variable:muc#roomconfig_allowinvites type:boolean value:[]
- variable:muc#roomconfig_passwordprotectedroom type:boolean value:[]
- variable:muc#roomconfig_roomsecret type:text-private value:[]
- variable:muc#roomconfig_whois type:list-single value:[]
- variable:muc#roomconfig_enablelogging type:boolean value:[]
- variable:x-muc#roomconfig_reservednick type:boolean value:[]
- variable:x-muc#roomconfig_canchangenick type:boolean value:[]
- variable:x-muc#roomconfig_registration type:boolean value:[]
- variable:muc#roomconfig_roomadmins type:jid-multi value:[]
- variable:muc#roomconfig_roomowners type:jid-multi value:[]
- */
- //submitForm.setAnswer(FormField.TYPE_TEXT_PRIVATE, "0");
- muc.sendConfigurationForm(submitForm);
- //被拒绝时执行
- muc.addInvitationRejectionListener(new InvitationRejectionListener() {
- @Override
- public void invitationDeclined(String invitee, String reason) {
- System.out.println(invitee + " : " + reason);
- }
- });
- muc.invite("yy@192.168.1.100", "ly_room");
- }
管理房间
[java] view plaincopy
- <pre name="code" class="java">private void testManageRoom(XMPPConnection conn) throws Exception {
- testCreateRoom(conn);
- MultiUserChat muc = new MultiUserChat(conn, "ly@conference.192.168.1.100");
- //Thread.sleep(5000);
- //赋予管理员权限
- //muc.grantAdmin("yy@192.168.1.100");
- //Thread.sleep(5000);
- //如果是管理员,则不能踢除
- //muc.banUser("yy@192.168.1.100", "太水");
- //收回说话的权限
- muc.revokeVoice("yy");
- //muc.grantVoice("yy");
- }
注册
[java] view plaincopy
- private void testRegister(XMPPConnection conn) throws Exception {
- //可以直接改登陆用户的信息(如果是username的值必须和该用户的用户名相同)
- Registration r = new Registration();
- Map<String, String> attributes = new HashMap<String, String>();
- attributes.put("username", "newuser");
- attributes.put("password", "0");
- attributes.put("email", "new00@126.com");
- attributes.put("name", "name@192.168.1.100");
- //添加用户,要设置type类型为set,原因不明
- r.setType(IQ.Type.SET);
- r.setAttributes(attributes);
- //过滤器,用来过滤由服务器返回的信息(即得到注册信息的内容)
- PacketFilter packetFilter = new AndFilter(new PacketIDFilter(r.getPacketID()), new PacketTypeFilter(IQ.class));
- PacketCollector collector = conn.createPacketCollector(packetFilter);
- System.out.println(r);
- conn.sendPacket(r);
- IQ result = (IQ) collector.nextResult();
- if(result == null) {
- System.out.println("服务器没有返回任何信息");
- } else {
- switch (result.getType().toString()) {
- case "result":
- System.out.println("注册成功");
- break;
- case "error":
- if(result.getError().toString().equalsIgnoreCase("conflict"))
- System.out.println("用户名称已存在");
- else
- System.out.println("注册失败");
- break;
- default:
- break;
- }
- }
- }
管理账号密码
[java] view plaincopy
- private void testModifyPwd(XMPPConnection conn) throws Exception {
- //创建一个用户信息管理,可以创建新用户,或者修改用户密码
- AccountManager am = AccountManager.getInstance(conn);
- Collection<String> c = am.getAccountAttributes();
- for(String s : c) {
- System.out.println(s);
- }
- /*
- * 通过accountManager可以得到的属性
- * username
- registered
- name
- password
- */
- am.getAccountAttribute("username");
- am.createAccount("newUser", "0");
- am.changePassword("00");
- }
至于细节和中间遇到的问题,在程序代码中都有叙述
参考博客:
http://blog.csdn.net/shimiso/article/details/11225873smark和openfire即时通信代码
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。