利用websocket实现android消息推送

前段时间做一个项目,需要android客户端作为管理工具与web服务器后台实时交互,想了很多方法,包括androidpn、openfire+smack、xmpp协议,要么太繁琐,要么无法满足实时性。想来还是用socket,经人提醒想到了websocket。

websocket协议是近些年随html5发展而诞生的,主要用于解决web服务器与客户端无法双向交互的问题。如今已经被W3C收入标准协议。

服务器支持:tomcat、jetty的最新版本都已支持websocket;如果不想更换现有服务器,也可用spring4.0作为替代。据说新版本的jre将收入websocket类,没具体接触。

客户端支持:目前的主流浏览器都已经实现了websocket,但由于前期协议版本变化太快,很多厂商没有跟上。android默认浏览器就不支持websocket,IE也直到IE10才支持。

网上已有通过html实现websocket client的例子,这里我们用java实现客户端连接。废话不说,上Demo:

1.服务器端

服务器用了tomcat 7.0,直接使用tomcat的websocket实现

1)连接管理类

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

import java.io.IOException;

import java.nio.CharBuffer;

import java.util.ArrayList;

import java.util.List;

import org.apache.catalina.websocket.MessageInbound;

import org.apache.catalina.websocket.WsOutbound;

public class MessageCenter

{

    private static MessageCenter        instance           = new MessageCenter();

    private List<MessageInbound>        socketList;

    private MessageCenter()

    {

        this.socketList = new ArrayList<MessageInbound>();

    }

    public static MessageCenter getInstance()

    {

        return instance;

    }

    public void addMessageInbound(MessageInbound inbound)

    {

        socketList.add(inbound);

    }

    public void removeMessageInbound(MessageInbound inbound)

    {

        socketList.remove(inbound);

    }

    public void broadcast(CharBuffer msg) throws IOException

    {

        for (MessageInbound messageInbound : socketList)

        {

            CharBuffer buffer = CharBuffer.wrap(msg);

            WsOutbound outbound = messageInbound.getWsOutbound();

            outbound.writeTextMessage(CharBuffer.wrap("broadcasting:" + msg));

            // outbound.writeTextMessage(buffer);

            outbound.flush();

        }

    }

}

2)消息入口类

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

import java.io.IOException;

import java.nio.ByteBuffer;

import java.nio.CharBuffer;

import java.util.Date;

import org.apache.catalina.websocket.MessageInbound;

import org.apache.catalina.websocket.WsOutbound;

public class MyMessageInbound extends MessageInbound {

    @Override

    protected void onBinaryMessage(ByteBuffer arg0) throws IOException {

        // TODO Auto-generated method stub

        

    }

    @Override

    protected void onTextMessage(CharBuffer msg) throws IOException {

        System.out.println("Received:"+msg);

        MessageCenter.getInstance().broadcast(msg);

        

    }

    @Override

    protected void onClose(int status) {

        System.out.println("close:"+new Date());

        MessageCenter.getInstance().removeMessageInbound(this);

        super.onClose(status);

    }

    @Override

    protected void onOpen(WsOutbound outbound) {

        System.out.println("open :"+new Date());

        super.onOpen(outbound);

        MessageCenter.getInstance().addMessageInbound(this);

    }

}

3)Websocket servlet

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

import javax.servlet.http.HttpServletRequest;

import org.apache.catalina.websocket.StreamInbound;

import org.apache.catalina.websocket.WebSocketServlet;

public class MeWebSocketServlet extends WebSocketServlet

{

    private static final long serialVersionUID = -7178893327801338294L;

    @Override

    protected StreamInbound createWebSocketInbound(String subProtocol, HttpServletRequest request)

    {

        System.out.println("##########client login#########");

        return new MeMessageInbound();

    }

}

4)添加servlet到web.xml

        < servlet>
               < servlet-name> android</ servlet-name >
               < servlet-class> MyWebSocketServlet </servlet-class >
        </ servlet>
        < servlet-mapping>
               < servlet-name> android</ servlet-name >
               < url-pattern> *.do</ url-pattern >
        </ servlet-mapping>

2.客户端

客户端使用java实现websocket client,

网上有人实现了Java-websocket:https://github.com/TooTallNate/Java-WebSocket 可以取得源码,用maven编译。

最新jar包下载地址:

http://download.csdn.net/detail/chifengxin/6524283

引用jar包后,实现简单消息连接:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

import java.net.URI;

import java.net.URISyntaxException;

import org.java_websocket.client.WebSocketClient;

import org.java_websocket.drafts.Draft;

import org.java_websocket.drafts.Draft_10;

import org.java_websocket.drafts.Draft_17;

import org.java_websocket.framing.Framedata;

import org.java_websocket.handshake.ServerHandshake;

/** This example demonstrates how to create a websocket connection to a server. Only the most important callbacks are overloaded. */

public class ExampleClient extends WebSocketClient {

        public ExampleClient( URI serverUri , Draft draft ) {

                super( serverUri, draft );

        }

        public ExampleClient( URI serverURI ) {

                super( serverURI );

        }

        @Override

        public void onOpen( ServerHandshake handshakedata ) {

                System.out.println( "opened connection" );

                // if you plan to refuse connection based on ip or httpfields overload: onWebsocketHandshakeReceivedAsClient

        }

        @Override

        public void onMessage( String message ) {

                System.out.println( "received: " + message );

        }

        @Override

        public void onFragment( Framedata fragment ) {

                System.out.println( "received fragment: " new String( fragment.getPayloadData().array() ) );

        }

        @Override

        public void onClose( int code, String reason, boolean remote ) {

                // The codecodes are documented in class org.java_websocket.framing.CloseFrame

                System.out.println( "Connection closed by " + ( remote ? "remote peer" "us" ) );

        }

        @Override

        public void onError( Exception ex ) {

                ex.printStackTrace();

                // if the error is fatal then onClose will be called additionally

        }

        public static void main( String[] args ) throws URISyntaxException {

                ExampleClient c = new ExampleClient( new URI( "ws://localhost:8080/myweb/android.do" ), new Draft_17() );

                c.connect();

        }

}

注意,连接中使用的new Draft_17()就是使用的协议version,Tomcat 7.0的协议版本需要高于Draft_17。

总结websocket的利弊

优点:

与socket相比,可以节省额外的端口占用,直接使用一个公网域名访问。另外协议对报文的流量消耗做了优化。

缺点:

毕竟websocket底层也是socket连接,因而当大并发用户连接时目测会消耗较多资源。

参考:

Tomcat 7.0 api http://tomcat.apache.org/tomcat-7.0-doc/api/

时间: 2024-11-10 06:27:12

利用websocket实现android消息推送的相关文章

Android消息推送:手把手教你集成小米推送

前言 在Android开发中,消息推送功能的使用非常常见. 为了降低开发成本,使用第三方推送是现今较为流行的解决方案. 今天,我将手把手教大家如何在你的应用里集成小米推送 该文档基于小米推送官方Demo,并给出简易推送Demo 看该文档前,请先阅读我写的另外两篇文章: 史上最全解析Android消息推送解决方案 Android推送:第三方消息推送平台详细解析 目录 1. 官方Demo解析 首先,我们先对小米官方的推送Demo进行解析. 请先到官网下载官方Demo和SDK说明文档 1.1 Demo

Android消息推送机制

1.推送方式基础知识: 当我们开发需要和服务器交互的应用程序时,基本上都需要获取服务器端的数据,比如<地震应急通>就需要及时获取服务器上最新的地震信息.要获取服务器 上不定时更新的信息一般来说有两种方法,第一种是客户端使用Pull(拉)的方式,隔一段时间就去服务器上获取信息,看是否有更新的信息出现.第二种就是 服务器使用Push(推送)的方式,当服务器端有新信息了,则把最新的信息Push到客户端上.? 虽然Pull和Push两种方式都能实现获取服务器端更新信息的功能,但是明显来说Push is

Android消息推送完美解决方案全析

推送功能在手机应用开发中越来越重要,已经成为手机开发的必须.在Android应用开发中,由于众所周知的原因,Android消息推送我们不得不大费周折.本文就是用来和大家共同探讨一种Android消息推送的完美解决方案. 一.消息推送基础 消息推送,就是在互联网上通过定期传送用户需要的信息来减少信息过载的一项新技术.推送技术通过自动传送信息给用户,来减少用于网络上搜索的时间.它根据用户的兴趣来搜索.过滤信息,并将其定期推给用户,帮助用户高效率地发掘有价值的信息 当我们开发需要和服务器交互的移动应用

Android消息推送

1.推送方式基础知识:  在移动互联网时代以前的手机,如果有事情发生需要通知用户,则会有一个窗口弹出,将告诉用户正在发生什么事情.可能是未接电话的提示,日历的提醒,或是一封新的彩信.推送功能最早是被用于Email中,用来提示我们新的信息.由于时代的发展和移动互联网的热潮,推送功能更加地普及,已经不再仅仅用在推送邮件了,更多地用在我们的APP中了. 当我们开发需要和服务器交互的应用程序时,基本上都需要获取服务器端的数据,比如<地震应急通>就需要及时获取服务器上最新的地震信息.要获取服务器上不定时

Android 消息推送 Xmpp协议

1.引言 所谓的消息推送就是从服务器端向移动终端发送连接,传输一定的信息.比如一些新闻客户端,每隔一段时间收到一条或者多条通知,这就是从服务器端传来的推送消息:还比如常用的一些IM软件如微信.GTalk等,都具有服务器推送功能. 推送方法如下: 1)通过SMS进行服务器端和客户端的交流通信. 在Android平台上,你可以通过拦截SMS消息并且解析消息内容来了解服务器的意图,可以实现完全的实时操作.但是问题是这个方案的成本相对比较高,且依赖于运营商. 2)循环主动定时获取 这种方法需要客户端来做

Android消息推送实现

在开发Android和iPhone应用程序时,我们往往需要从服务器不定的向手机客户端即时推送各种通知消息,iPhone上已经有了比较简单的 和完美的推送通知解决方案,可是Android平台上实现起来却相对比较麻烦,最近利用几天的时间对Android的推送通知服务进行初步的研究. 在Android手机平台上,Google提供了C2DM(Cloudto Device Messaging)服务,起初我就是准备采用这个服务来实现自己手机上的推送功能. Android Cloud to Device Me

5.Android消息推送机制简单例子

1.首先布局文件xml代码: 1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:tools="http://schemas.android.com/tools" 4 android:layout_width=&

springboot整合websocket实现一对一消息推送和广播消息推送

maven依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> 常量类 //webSocket相关配置 //链接地址 public static String WEBSOCKETPATHPERFIX = "/ws-push&

Android消息推送 SDK 集成指南

使用提示 本文是 Android SDK 标准的集成指南文档. 匹配的 SDK 版本为:r1.8.0及以后版本. 本文随SDK压缩包分发.在你看到本文时,可能当前的版本与本文已经不是很适配.所以建议关注在线文档: 3 分钟快速 Demo(Android):如果您想要快速地测试.感受下极光推送的效果,请参考本文在几分钟内跑通Demo. 极光推送文档网站上,有极光推送相关的所有指南.API.教程等全部的文档.包括本文档的更新版本,都会及时地发布到该网站上. 极光推送问答网站:大家除了文档之外,还有问