最近要做个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了
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也可以收到。
做到了长连接。
附上: 源码下载地址