Skip to content

Instantly share code, notes, and snippets.

@lanrion
Last active August 29, 2015 14:01
Show Gist options
  • Save lanrion/3f14ed88ada29e2765b4 to your computer and use it in GitHub Desktop.
Save lanrion/3f14ed88ada29e2765b4 to your computer and use it in GitHub Desktop.
Java 甲骨文技术沙龙分享会--WebSocket总结

WebSocket

常规网站实现“实时”的方式:

1)轮询(JavaScript中的setInterval) 最简单的是前台轮询,每隔一段时间去请求后台,以获取最新状态,这种方式最容易实现,但效果也最差,频繁盲目的调用后台,带来不必要的开销,且实时性无法保障,后台出现更新,前端需要在下一次轮询时才知道。

2)长轮询 为了解决这些弊端,进化出长轮询技术,轮询请求会在后台阻塞,相当于保持一个长连接,直到后台出现更新或者超时才返回,这样就可以保证更新的及时性,前端得到请求后,重新建立轮询连接,等待后台的更新通知。

但这几种模式:实现上复杂,效率低效,资源浪费,并非做到真正的实时。

WebSocket

概念

html5规范新引入的功能,用于解决浏览器与后台服务器双向通讯的问题,使用WebSocket技术,后台可以随时向前端推送消息,以保证前后台状态统一,在传统的无状态HTTP协议中,这是“无法做到”的。WebSocket的服务器链接形式为:"ws://localhost:8080/hello-websocket/hello"

需要浏览器支持

使用JavaScript检测:

window.WebSocket = window.WebSocket || window.MozWebSocket;
if (!window.WebSocket){
    alert("WebSocket not supported by this browser");
    return;
}

附图:

Resize icon

需要服务器的支持

服务器支持附图:

Resize icon

WebSocket的握手连接

1、Client发送握手请求;

2、Server返回握手应答;

3、连接之后,开始进行消息通信;

附图:

Resize icon

WebSocket的事件与方法调用

事件 open/message/close/error

WebSocket#onopen, onmessage, onclose, onerror

连接打开时,回调onopen方法,接收到后台消息时会触发到onmessage事件,后台关闭时调用onclose,出现连接异常时可在onerror中捕获。

方法 – send/close

发送消息 – WebSocket#send(data) 关闭连接 – WebSocket#close(optional code, optional reason)

发送消息例子:

websocket.send(JSON.stringify({action: "node.remove", id: "001"}));

简单使用

在JavaScript中使用WebSocket

var wsUri = "ws://localhost:8080/hello-websocket/hello";
var websocket = new WebSocket(wsUri);

# 处理建立连接事件
websocket.onopen = function(evt) { onOpen(evt) };
# 处理接收信息事件
websocket.onmessage = function(evt) { onMessage(evt) };
# 处理出错事件
websocket.onerror = function(evt) { onError(evt) };

对应Java的实现

import javax.websocket.OnMessage;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint("/hello")
public class HelloBean {

    @OnMessage
    public String sayHello(String name) {
        return "Hello " + name + "!";
    }
}

Java API for WebSocket

JSR 356: Java API for Web Socket

1)Java API 规范

http://jcp.org/en/jsr/detail?id=356http://java.net/projects/websocket-spec – Included in Java EE 7

2)参考实现

http://java.net/projects/tyrus – Bundled with Glassfish 4

Java API在WebSocket上的特性

1,两种方式创建 Endpoints

– Interface-driven (Endpoint) – Annotation-driven (@ServerEndpoint)

2,提供客户端,服务端的API

3,SPI for extensions and data frames(不太理解)

使用 Interface-driven实现

Endpoint: Intercepts WebSocket lifecycle events

MessageHandler: Handles all incoming messages for an Endpoint

RemoteEndpoint: Represents the ‘other end’ of this conversation

Session: Represents the active conversation

  • Server:
public class HelloServer extends Endpoint {
  @Override
  public void onOpen(Session session, EndpointConfig configuration) {
    session.addMessageHandler(
      new MessageHandler.Whole<String>() {
        public void onMessage(String name) {
          try {
            session.getBasicRemote().sendText(“Hello “ + name);
          } catch (IOException ioe) {
          // Handle failure.
          }
        }
    });
  }
}
  • Client:
public class HelloClient extends Endpoint {
  @Override
  public void onOpen(Session session, EndpointConfig configuration) {
    try {
      session.getBasicRemote().sendText("Hello you!");
    } catch (IOException ioe) {
    . . .
    }
  }
}

使用POJO-Annotation实现(更简介)

  • 使用示例
@ServerEndpoint("/hello")
public class HelloBean {
  
  @onMessage
  public String sayHello(String name){
    return "Hello" + name;
  }
}
  • WebSocket Annotations 接口介绍

1,@ServerEndpoint,将一个类声明为WebSocket的服务器端点

2,@ClientEndpoint,将一个类声明为WebSocket的客户端点

3,@OnOpen,拦截 WebSocket 打开事件

4,@OnClose,拦截WebSocket关闭事件

5,@OnMessage,拦截WebSocket的消息事件

6,@PathParam,一个URI模板的标记匹配的路径段

7,@OnError,拦截在一个会话当中的出现的错误

关于WebSocket的更多介绍,可以查看:http://docs.oracle.com/javaee/7/tutorial/doc/websocket.htm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment