天天看點

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也可以收到。

做到了長連接配接。

附上: 源碼下載下傳位址