天天看点

android websocket长连接推送

最近要做个android websocket推送的功能,也不知道什么好,网上找了半天都是web间聊天系统,后来查到了autobahnandroid,之后搞通了,现在分享一下自己的简单例子。

autobahn是一个android的WebSocket 和WAMP 客户端运行库。

首先,服务端:(网上可以查到很多)

package com.servlet;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.StreamInbound;
import org.apache.catalina.websocket.WebSocketServlet;
import org.apache.catalina.websocket.WsOutbound;

public class ChatWebSocketServlet extends WebSocketServlet {
	/**
	 * 
	 */
	public static final long serialVersionUID = 911879078000755859L;
	//private final Map<Integer, WsOutbound> map = new HashMap<Integer, WsOutbound>();
	public final Map<String,WsOutbound> users = new HashMap<String,WsOutbound>();

	
	@Override
	protected StreamInbound createWebSocketInbound(String arg0, HttpServletRequest request)
	{
		String username = null;
		try {
			username = request.getParameter("username");
			System.out.println(username);
			if(username != null){
				username = new String(username.getBytes("ISO8859_1"),"UTF-8");
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(username+" 请求连接:");
		return new ChatMessageInbound(username);
	}

	public class ChatMessageInbound extends MessageInbound{
		
		private String userName = "user";
		
		public ChatMessageInbound(String userName) {
				this.userName = userName;
		}
		//连接websocket服务器时进行的event
		@Override
		protected void onOpen(WsOutbound outbound) {
			users.put(userName, outbound);
			System.out.println(userName+"上线了,总共"+users.size()+"人在线");
			super.onOpen(outbound);
		}
		//关闭时的动作
		@Override
		protected void onClose(int status) {
			users.remove(userName);
			System.out.println("下线:"+userName);
			super.onClose(status);
		}
		// 有二进制消息数据到达,比如音频等文件传输
		@Override
		protected void onBinaryMessage(ByteBuffer buffer) throws IOException {
			// TODO Auto-generated method stub
		}
		//收到信息时的动作
		@Override
		protected void onTextMessage(CharBuffer buffer) throws IOException {

			String msg = buffer.toString();
			System.out.println(userName+":"+msg);
			Date date = new Date();
			SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
//			msg = userName+" " + sdf.format(date)+":\n" + msg;
			broadcast(msg);
		}

		private void broadcast(String msg) {
			Set<String> set = users.keySet();
			for (String name : set) 
			{
					WsOutbound outbound = users.get(name);

					CharBuffer buffer = CharBuffer.wrap(msg);
					try {
							outbound.writeTextMessage(buffer);
							outbound.flush();
					} catch (Exception e) {
						e.printStackTrace();
					}
				System.out.println(name+"----");
				
			}
		}
	}
}
           

web.xml

<!-- WebSocket -->
    <servlet>
      <servlet-name>androidSocket</servlet-name>
      <servlet-class>com.servlet.ChatWebSocketServlet</servlet-class>
    </servlet>
    <servlet-mapping>
      <servlet-name>androidSocket</servlet-name>
      <url-pattern>/chat.ws</url-pattern>
    </servlet-mapping>
           

就这么多。其实就是一个servlet

android端:

只要调用autobahn的3个jar包就一切ok了

android websocket长连接推送
package com.example.mywebsockettest;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;
import de.tavendo.autobahn.WebSocketConnection;
import de.tavendo.autobahn.WebSocketException;
import de.tavendo.autobahn.WebSocketHandler;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	
	private static final String TAG = "de.tavendo.test1";

	private final WebSocketConnection mConnection = new WebSocketConnection();
	   
	public void open_websocket (View source){
		final String wsuri = "ws://192.168.100.170:8080/websocket01/chat.ws?username=wangyue";

		try {
			mConnection.connect(wsuri, new WebSocketHandler() {

				@Override
				public void onOpen() {
					Log.d(TAG, "Status: Connected to " + wsuri);
					mConnection.sendTextMessage("Hello, world!");
				}

				@Override
				public void onTextMessage(String payload) {
					Log.d(TAG, "Got echo: " + payload);
					Toast.makeText(getApplicationContext(), "长连接返回:"+payload, 0).show(); 
				}

				@Override
				public void onClose(int code, String reason) {
					Log.d(TAG, "Connection lost.");
				}
			});
		} catch (WebSocketException e) {
			Log.d(TAG, e.toString());
		}
   }
}
           

服务端统计上线人数,之后访问http://192.168.100.170:8080/websocket01/MyJsp.jsp

android调用open函数时可以sendTextMessage发送消息

服务端前台界面可以在input中发送消息,android也可以收到。

做到了长连接。

附上: 源码下载地址