1. 什么是WebSocket?菜鸟对websocket的解释如下

  WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

  WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

  在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

  现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询(我目前接触的线上聊天也确实是基于这种方式实现的)。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

  HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯

 

  浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。

  当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。

以下 API 用于创建 WebSocket 对象。

var Socket = new WebSocket(url, [protocol] );

 

WebSocket 属性

属性描述

Socket.readyState

只读属性 readyState 表示连接状态,可以是以下值:

0 - 表示连接尚未建立。

1 - 表示连接已建立,可以进行通信。

2 - 表示连接正在进行关闭。

3 - 表示连接已经关闭或者连接不能打开。

Socket.bufferedAmount

只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。

 

WebSocket 事件:

事件事件处理程序描述

open

Socket.onopen

连接建立时触发

message

Socket.onmessage

客户端接收服务端数据时触发

error

Socket.onerror

通信发生错误时触发

close

Socket.onclose

连接关闭时触发

WebSocket 方法:

方法描述

Socket.send()

使用连接发送数据

Socket.close()

关闭连接

 

2. Tomcat中开发简单的WebSocket实例

  在这里实现一个简易的聊天室。

开发环境:JDK7+Tomcat7.0.91(如果连接URL报404建议切换tomcat为高版本,我在7.0.88测试就连接不到后端)

最终效果如下:

 

代码如下:

后端:

package chat;

import java.io.IOException;

import java.util.HashMap;

import javax.websocket.OnClose;

import javax.websocket.OnError;

import javax.websocket.OnMessage;

import javax.websocket.OnOpen;

import javax.websocket.Session;

import javax.websocket.server.ServerEndpoint;

@ServerEndpoint("/chat")

public class ChatServer {

private boolean first = true;

private String name;

private Session session;

private static final HashMap clientSet = new HashMap();

public ChatServer() {

System.out.println("========ChatServer创建============");

}

/*

* 客户端连接时触发该方法

*/

@OnOpen

public void onOpen(Session session) throws IOException {

this.session = session;

}

/*

* 客户端断开时触发该方法

*/

@OnClose

public void onClose() {

clientSet.remove(name);

String message = String.format("【%s %s】", name, "离开了聊天室!");

broadcast(message);

}

/*

* 客户端收到消息时触发该方法

*/

@OnMessage

public void onMessage(String msg) {

if (first) {

name = msg;

clientSet.put(name, this);

String message = String.format("【%s %s】", name, "加入了聊天室!");

// 发送消息

broadcast(message);

first = false;

} else {

broadcast("【" + name + "】" + ":" + msg);

}

}

// 当客户端通信出现错误时,激发该方法

@OnError

public void onError(Throwable t) throws Throwable {

System.out.println("WebSocket服务端错误 " + t);

}

public void broadcast(String msg) {

// 遍历服务器关联的所有客户端

ChatServer client = null;

for (String nickname : clientSet.keySet()) {

try {

client = (ChatServer) clientSet.get(nickname);

synchronized (client) {

// 发送消息

client.session.getBasicRemote().sendText(msg);

}

} catch (IOException e) {

System.out.println("聊天错误,向客户端 " + client + " 发送消息出现错误。");

clientSet.remove(name);

try {

client.session.close();

} catch (IOException e1) {

}

String message = String.format("【%s %s】", client.name, "已经被断开了连接。");

broadcast(message);

}

}

}

}

 

 前端:

简单聊天室

style="width: 600px; height: 240px; overflow-y: auto; border: 1px solid #333;"

id="show">