除聊天文本外的 Smack 消息传递客户端

Posted

技术标签:

【中文标题】除聊天文本外的 Smack 消息传递客户端【英文标题】:Smack messaging client other than Chat Text 【发布时间】:2010-07-11 03:06:42 【问题描述】:

client1 可以使用

向 client2 发送 txt 消息
connection.getChatManager().createChat(to, this).sendMessage(message);

如何发送其他类型的消息:如 INFO 消息? (客户端 1 到客户端 2)?

因为我想要,INFO消息不应该显示在聊天窗口中....有可能吗?使用 smack、smackx 库。

非常感谢。

【问题讨论】:

【参考方案1】:

您在这里要做的是为您的短信添加扩展名。这是一个粗略的指南。

Chat chat = connection.getChatManager().createChat(to, this);
Message message = new Message(to, Message.Type.chat);
message.setBody("hello");
message.setProperty(prop0, val0);
message.setProperty(prop1, val1);
chat.sendMessage(message)

属性在单独的命名空间中携带(使用toXML()查看),不会出现在聊天窗口中。在“另一边”,应用程序使用getProperty() 来检索值。

如果您不需要键/值对,而是结构化数据,请在消息正文中使用 addExtension()。这有点复杂,因为您基本上必须扩展PacketExtension,提供您自己的命名空间。你甚至可能不得不写一个PacketExtensionProvider

【讨论】:

【参考方案2】:

这是消息扩展的示例。 XMPP协议的基本XML结构是:

<message  
    from='sender_jid'  
    to='receiver_jid'  
    type='message_type'>  
  <body> content </body>  
</message> 

发送消息的过程:

//build chat  
Chat chat = chatManager.createChat("jid");  

//build extension  
UserInfo4XMPP userInfo4XMPP = new UserInfo4XMPP();  
userInfo4XMPP.setNameText("userx");  
userInfo4XMPP.setUrlText("http://www.liaoku.org/");  

//build message  
Message message = new Message();  
message.setBody("hello");  
message.addExtension(userInfo4XMPP);// add the extension  

//send  
chat.sendMessage(message); 

UserInfo4XMPP定义为:

import org.jivesoftware.smack.packet.ExtensionElement;  

public class UserInfo4XMPP implements ExtensionElement  

    private String elementName = "userinfo";   
    private String nameElement = "name";  
    private String urlElement = "url";  
    private String nameText = "";  
    private String urlText = "";  

    @Override  
    public String getElementName()   
        return elementName;  
      

    @Override  
    public CharSequence toXML()   
        StringBuilder sb = new StringBuilder();  

        sb.append("<");  
        sb.append(elementName);  
        sb.append(">");  

            sb.append("<");  
            sb.append(nameElement);  
            sb.append(">");  
            sb.append(nameText);  
            sb.append("</");  
            sb.append(nameElement);  
            sb.append(">");  

            sb.append("<");  
            sb.append(urlElement);  
            sb.append(">");  
            sb.append(urlText);  
            sb.append("</");  
            sb.append(urlElement);  
            sb.append(">");  

        sb.append("</");  
        sb.append(elementName);  
        sb.append(">");  

        return sb.toString();  
      

    @Override  
    public String getNamespace()   
        return "";  
      

    public String getNameText()   
        return nameText;  
      

    public void setNameText(String nameText)   
        this.nameText = nameText;  
      

    public String getUrlText()   
        return urlText;  
      

    public void setUrlText(String urlText)   
        this.urlText = urlText;  
      

【讨论】:

【参考方案3】:

一个更复杂的消息扩展示例:

Message videoMsg = new Message();
VideoChatRTP videoXml = new VideoChatRTP();
videoXml.setVideoType(VideoMediaType.REQUEST);
videoXml.setAddress(address);
videoMsg.setTo(receive);
videoMsg.addExtension(videoXml);
XMPPConnection conn = BaseService.getInstance().getConnection();
conn.sendPacket(videoMsg);

扩展类 VideoChatRIP 必须实现 PacketExtension:

public class VideoChatRTP implements PacketExtension 
    private VideoMediaType videoType;
    private String address;
    public String getAddress() 
        return address;
    
    public void setAddress(String address) 
        this.address = address;
    
    public VideoMediaType getVideoType() 
        return videoType;
    
    public void setVideoType(VideoMediaType videoType) 
        this.videoType = videoType;
    
    public static final String NAME = "jingle";
    public static final String NAME_SPACE = "com:roger:video";
    public VideoChatRTP() 
        super();
    
    @Override
    public String getElementName() 
        return NAME;
    
    @Override
    public String getNamespace() 
        return NAME_SPACE;
    
    @Override
    public String toXML() 
        StringBuffer sb = new StringBuffer();
        sb.append("<jingle").append(" xmlns=\"").append(NAME_SPACE).append(
                "\">");
        sb.append("<type>").append(videoType).append("</type>");
        sb.append("<ipAddress>").append(address).append("</ipAddress>");
        sb.append("</jingle>");
        return sb.toString();
    

聆听者:

ProviderManager.getInstance().addExtensionProvider(VideoChatRTP.NAME, VideoChatRTP.NAME_SPACE, new VideoChatReceive());

处理:

public class VideoChatReceive implements PacketExtensionProvider 
    @Override
    public PacketExtension parseExtension(XmlPullParser parser)
            throws Exception 
        boolean done = false;
        String requestType = "asdasd";
        String ipAddress = "asdasd";
        while (!done) 
            int eventType = parser.next();
            String name = parser.getName();
            if (eventType == XmlPullParser.START_TAG) 
                if (name.equals("type")) 
                    requestType = parser.nextText();
                
                if (name.equals("ipAddress")) 
                    ipAddress = parser.nextText();
                
            
            if (eventType == XmlPullParser.END_TAG) 
                if (name.equals("jingle")) 
                    done = true;
                
            
        
        VideoChatRTP videoRtp = new VideoChatRTP();
        videoRtp.setVideoType(VideoMediaType.valueOf(requestType));

        videoRtp.setAddress(ipAddress);
        return videoRtp;
    

【讨论】:

以上是关于除聊天文本外的 Smack 消息传递客户端的主要内容,如果未能解决你的问题,请参考以下文章

谷歌云消息传递 - 使用 smack 的 xmpp 服务器端不起作用

如何将receiptid映射到smack中发送的消息

XMPP Smack 聊天应用程序中的多设备支持

使用 smack 的多用户聊天没有收到消息侦听器

使用聊天消息

将聊天消息传递给离线用户的问题