XMPP、Ejabberd类似微信即时通讯服务器(Android IM 服务端功能开发第一篇)

XMPP

简单说XMPP是由IETF制定的一个可扩展的即时消息通信协议。XMPP基本有两部分组成,一部分是它的核心协议,还有一部分是扩展协议。

其中核心协议主要由RFC-6120、RFC-6121、RFC-6122组成。

还有一堆的扩展协议,具体可以参见XMPP官网扩展协议列表部分。一般会使用到得扩展协议包括XEP-0160 XEP-0013离线消息处理、xep-0045多用户聊天、XEP-0096文件传输

XMPP具有的一些基本性质如下:

基于XML

标准

可扩展

Ejabberd

Ejabberd(Erlang)可以说是最棒的XMPP Server了吧,另外Openfire(Java)也是一个比较不错的XMPP Server实现。个人虽然是Java开发者,但还是更倾向于使用Erlang开发的Ejabberd,原因是Erlang自身具备的容错性和强大的无痛水平扩展能力确实比Java要高明很多。同时Ejabberd的安装和使用都非常爽快,属于是开箱即用类型的,而且文档也很齐全。
安装采用的是傻瓜式的安装,非源码安装。

1、Ejabberd的开发语言是Erlang,首先安装Erlang。

apt-get install erlang

2、安装Ejabberd

apt-get install ejabberd

3、启动一个ejabberd实例

ejabberdctl start

配置和管理

当你启动一个ejabberd实例后,事实上你就可以直接用了,当然如果你需要深入的使用一些特性,还是需要做一些简单的配置的。

ejabberd默认的配置文件在/etc/ejabberd/ejabberd.cfg。

有一些配置在配置文件中被注释了的,Erlang是用百分号%作为注释语法,如果要使用这个配置删除%号就可以了。

另外erlang提供了一个web管理界面,首先先通过下面的这条命令注册一个XMPP管理账号。

ejabberdctl register user host password

如果使用默认的端口配置的话就可以用这个链接http://server:5280/admin/登录到web管理控制台了。

Smack

Smack是Java语言写的XMPP Library,个人观察下来貌似也是Java下最好得XMPP客户端了。下面演示一下实际IM场景中最基本的几个需求用Smack怎么来实现。
链接与登录
localhost 也就是Ejabberd的服务的域名

ConnectionConfiguration config = new ConnectionConfiguration("192.168.16.16", 5222, "localhost");
connection = new XMPPConnection(config);
connection.connect();
connection.login("zhuxiaohao", "123456", "zhuxiaohao");

登录后可以在web管理界面中看到用户在线得状态,前提是与Ejabberd的连接不能断,比如你就不能紧接着运行disconnect()了,这个和数据库之类的连接比起来是一个很大的差别,原因是XMPP协议本身就是长连接的。

可以通过setSendPresence(boolean sendPresence)来控制隐身登录。

聊天

ChatManager chatmanager = connection.getChatManager();
Chat newChat = chatmanager.createChat("chenhao@localhost", new MessageListener() {
    public void processMessage(Chat chat, Message message) {
        System.out.println("Received message: " + message);
    }
});
try {
    newChat.sendMessage("hello!");
}
catch (XMPPException e) {
    System.out.println("Error 连接失败");
}

接收

connection.getChatManager().addChatListener(new ChatManagerListener() {
    @Override
    public void chatCreated(Chat chat, boolean createdLocally) {
        chat.addMessageListener(new MessageListener() {
            @Override
            public void processMessage(Chat chat, Message message) {
                System.out.println(message.getBody());
            }
        });
    }
});

离线消息处理
下面的这种处理方式可以用于在线状态登录时离线消息的接收,如果需要在离线状态也可以接收到离线消息时,可以用OfflineMessageManager来控制,但是需要注意,比较坑爹的是Ejabberd的Community Server版本并不支持XEP-0013Flexible Offline Message Retrieval 这个协议,所以OfflineMessageManager也就用不了啦。

好在Smack在很多协议API中都有关于服务端是否支持此协议的API。比如下面这种

public boolean supportsFlexibleRetrieval()
ConnectionConfiguration config = new ConnectionConfiguration("192.168.16.16", 5222, "localhost");
config.setSendPresence(true);
Connection conn = new XMPPConnection(config);
conn.connect();
conn.addPacketListener(new PacketListener() {
    @Override
    public void processPacket(Packet packet) {
        DelayInformation delay = (DelayInformation)packet.getExtension("x", "jabber:x:delay");
        if(delay == null) {
            return;
        }
        if(packet instanceof Message) {
            System.out.println(((Message)packet).getBody());
        }
    }
}, null);
conn.login("zhuxiaohao", "123456", "zhuxiaohao");

发送文件
发送

FileTransferManager fileTransferManager = new FileTransferManager(connection);
// Create the outgoing file transfer
OutgoingFileTransfer transfer = fileTransferManager.createOutgoingFileTransfer("mahaiyue@localhost/test");
// Send the file
transfer.sendFile(new File(TestMessaging.class.getResource("origin").toURI()), "You won't believe this!");
Thread.sleep(5000);
System.out.println(transfer.getException());  
System.out.println(transfer.getProgress());  
System.out.println(transfer.isDone());  

接收

manager.addFileTransferListener(new FileTransferListener() {
      public void fileTransferRequest(FileTransferRequest request) {
            // Check to see if the request should be accepted
            if(shouldAccept(request)) {
                  // Accept it
                  IncomingFileTransfer transfer = request.accept();
                  try {
                    transfer.recieveFile(new File("test.java"));
                }
                catch (XMPPException e) {
                    e.printStackTrace();
                }
            } else {
                  // Reject it
                  request.reject();
            }
      }
    private boolean shouldAccept(FileTransferRequest request) {
        System.out.println(request.getMimeType());
        return true;
    }
});

有没有觉得很简单,打造属于自己的 IM聊天工具.感觉有木有很流弊.一系列文章小生会陆续写出来,晚上回去加班写代码,白天要上班,时间有限.所以出的慢点了.

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值