X.d 笔记

小Web,大世界

0%

HTML5 - WebSocket 简单使用

看到 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();
        }
    }
}

从代码来看,也就这么几步

  1. JavaScript 建立连接,注册onOpen,onMessage,onClose
  2. 执行Java的的注解 @OnOpen / 连接成功后JavaScript的onOpen也会触发
  3. Java处理完后使用session.getBasicRemote().sendText(msg)返回信息
  4. JavaScript 里面的 onMessage接收,处理
  5. JavaScript后续只用调用 socket.send(sendText);就可以了,onMessage会自动接收

对于onmessage方法,注解提供了一些参数规格,可以传文本,二进制和pong消息,可以分别实现命令,上传文件,PING调试等功能,API如下,在下便不翻译了。

  1. 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).
  1. 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).
  1. if the method is handling pong messages:
  • PongMessage for handling pong messages

Chrome 和 FireFox 现在都支持 WebSocket 了,如果不考虑 IE 用户的话其实是可以用的,但个人感觉有个设计上缺点:对于页面上来说,肯定是希望 WebSocket 对象越少越好,最好一个 WebSocket 能够搞定所有的事情,但对于服务来说,目前没有一个类似 MVC 框架的控制层。也就是说目前如果使用的话,可能 Java 代码会很复杂,只能靠自身的智慧去解决了。