关于WebSocket,个人理解是一种网络协议,好比http,好处在于可以建立一条服务器与客户端长久的连接,从而减少每次通信都需重新建立连接而产生的损耗;缺点在于如果客户端是智能设备,当处于休眠状态时,会自动关闭网络(未测试),还有长链接的流量大小(未测试)。用途多在于即时通信,网上聊天室等。websocket 简介:http://www.html5rocks.com/zh/tutorials/websockets/basics/
服务端是用tomcat7,该版本已支持websocket,很方便。注意7.0.38之前版本会出现长链接自动断开,之后的版本修复了这个问题,我当前的版本是7.0.42.
@WebServlet("/sosWebSocketService") //服务名称
public class TestWebSocketServlet extends WebSocketServlet{
private final Map map = new HashMap(); //注册客户端
/**
*
*/
private static final long serialVersionUID = -1058445282919079067L;
@Override
protected StreamInbound createWebSocketInbound(String arg0, HttpServletRequest req) {
return new ChatMessageInbound(req.getParameter("userCode"));
}
class ChatMessageInbound extends MessageInbound {
private String key = "";
public ChatMessageInbound(String key) {
this.key = key;
}
@Override
protected void onOpen(WsOutbound outbound) {
map.put(key, outbound);
super.onOpen(outbound);
}
@Override
protected void onClose(int status) {
map.remove(key);
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(); //接受客户端消息
broadcast(msg);
}
private void broadcast(String msg) {
Set set = map.keySet();
for (String integer : set) {
WsOutbound outbound = map.get(integer);
CharBuffer buffer = CharBuffer.wrap(msg);
try {
outbound.writeTextMessage(buffer); //向客户端发送消息
outbound.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
android端:autobahn 官网: http://autobahn.ws/ 里面有详细说明,还有测试demo下载。我用了service的机制去实现,即时退出应用,服务仍可在后台运行,给出的代码去掉了次要的部分。
public class SosWebSocketClientService extends Service{
private final String TAG = "SosWebSocketClientService";
private final WebSocketConnection mConnection = new WebSocketConnection();
SharedPreferencesUtil spu;
private final IBinder mBinder = new SosWebSocketClientBinder();
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public void onCreate() {
spu = new SharedPreferencesUtil(SosWebSocketClientService.this, SharedPreferencesUtil.STR_XMLFILE);
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
initWebSocket();
super.onCreate();
Log.d(TAG, "Service Create");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
/**
* 销毁
*/
@Override
public void onDestroy() {
if (mConnection.isConnected()) {
mConnection.disconnect();
}
super.onDestroy();
Log.d(TAG, "Service Destroy");
}
private void initWebSocket(){
//注意连接和服务名称要一致
/*final String wsuri = "ws://192.168.0.2:8080/st/sosWebSocketService?userCode="
+ spu.getValue(LoginActivity.STR_USERNAME);*/
Log.d(TAG, Config.getSosWebSocketUrl() + "/userCode=" + spu.getValue(SharedPreferencesUtil.STR_USERCODE));
final String wsuri = Config.getSosWebSocketUrl() +
"?userCode=" + spu.getValue(SharedPreferencesUtil.STR_USERCODE);
try {
mConnection.connect(wsuri, new WebSocketHandler() {
@Override
public void onOpen() {
Log.i(TAG, "WebSocket open");
}
@Override
public void onTextMessage(String text) {
Log.i(TAG, "onTextMessage");
showNotification(text);
}
@Override
public void onClose(int code, String reason) {
Log.i(TAG, "Connection lost.");/*alert("Connection lost.");*/
}
});
} catch (WebSocketException e) {
Log.d(TAG, e.toString());
}
}
public class SosWebSocketClientBinder extends Binder {
public SosWebSocketClientService getService() {
return SosWebSocketClientService.this;
}
public void sendXxx(String addr){
if(mConnection.isConnected())
mConnection.sendTextMessage("xxx");
}
}
}