看到 Tomcat7 支持 WebSocket,对于新东西,总是想先趟一趟水,看能给项目增加点光彩。
简单写了一个 Demo,基础部分还是挺简单。
html & JavaScript :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>WebSocket</title>
<script type="text/javascript" src="jquery.js"></script>
<style type="text/css">
button{
border: 1px solid #ccc;
background-color: #333;
padding: 3px;
opacity: 0.8;
color: #fff;
}
div{
width:400px;
height:200px;
border:1px solid #cccccc;
border-radius: 3px;
}
div p{
line-height: 20px;
font-size: 12px;
margin: 0;
}
</style>
</head>
<body>
<header></header>
<div id="comand"></div>
<button>OPEN</button><button>NAME</button><button>AGE</button><button>CLOSE</button>
<footer></footer>
</body>
<script>
var host = "ws://localhost:8080/test/wstest";
var socket = null;
function log(msg){
$('#comand').append('<p>'+msg+'</p>');
};
function initpage(){
$('button').click(buttonClick);
}
function buttonClick(e){
var sendText = $(e.currentTarget).text();
log('click:'+sendText);
if(sendText=='OPEN'){
if(socket==null){
socket = new WebSocket(host);
log('WebSocket - status '+socket.readyState);
socket.onopen = function(msg){ log("Welcome - status "+this.readyState); };
socket.onmessage = function(msg){ log("Received: "+msg.data); };
socket.onclose = function(msg){ log("Disconnected - status "+this.readyState); };
}else{
log('WebSocket - was initnailed');
}
}else if(sendText=='CLOSE'){
socket.close();
socket=null;
}else{
socket.send(sendText);
}
}
$(document).ready(initpage);
</script>
</html>
Java代码:
package com.xdnote.socket;
import java.io.IOException;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint(value = "/wstest")
public class Socket {
private Session session=null;
@OnOpen
public void onOpen(Session session){
this.session=session;
this.returnMsg("welcome");
}
@OnMessage
public void onMessage(String message){
if(message.equals("NAME")){
this.returnMsg("gaga");
}else if(message.equals("AGE")){
this.returnMsg("15");
}
}
private void returnMsg(String msg){
try {
this.session.getBasicRemote().sendText(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
从代码来看,也就这么几步
- JavaScript 建立连接,注册onOpen,onMessage,onClose
- 执行Java的的注解 @OnOpen / 连接成功后JavaScript的onOpen也会触发
- Java处理完后使用session.getBasicRemote().sendText(msg)返回信息
- JavaScript 里面的 onMessage接收,处理
- JavaScript后续只用调用 socket.send(sendText);就可以了,onMessage会自动接收
对于onmessage方法,注解提供了一些参数规格,可以传文本,二进制和pong消息,可以分别实现命令,上传文件,PING调试等功能,API如下,在下便不翻译了。
- if the method is handling text messages:
- String to receive the whole message
- Java primitive or class equivalent to receive the whole message converted to that type
- String and boolean pair to receive the message in parts
- Reader to receive the whole message as a blocking stream
- any object parameter for which the endpoint has a text decoder (Decoder.Text or Decoder.TextStream).
- if the method is handling binary messages:
- byte[] or ByteBuffer to receive the whole message
- byte[] and boolean pair, or ByteBuffer and boolean pair to receive the message in parts
- InputStream to receive the whole message as a blocking stream
- any object parameter for which the endpoint has a binary decoder (Decoder.Binary or Decoder.BinaryStream).
- if the method is handling pong messages:
- PongMessage for handling pong messages
Chrome 和 FireFox 现在都支持 WebSocket 了,如果不考虑 IE 用户的话其实是可以用的,但个人感觉有个设计上缺点:对于页面上来说,肯定是希望 WebSocket 对象越少越好,最好一个 WebSocket 能够搞定所有的事情,但对于服务来说,目前没有一个类似 MVC 框架的控制层。也就是说目前如果使用的话,可能 Java 代码会很复杂,只能靠自身的智慧去解决了。