您的位置:首页 > 其它

WebSocket ——多人实时聊天

2016-04-07 21:36 309 查看
严格来说,WebSocket并不属于 Java Web相关规范,属于HTML 5 规范的一部分;

WebSocket 允许通过JavaScript 建立与服务器的连接,从而允许远程服务器将数据推送给浏览器。

使用WebSocket,可以构建实时性较高的应用,比如:在线游戏、在线证券、设备监控、新闻在线播报等,职业服务器有新数据,就可以将数据推送给浏览器,让浏览器显示最新的状态。

使用Tomcat 8开发WebSocket服务端非常简单,有两种方式:

——使用注解@ServerEndpoint

——继承Endpoint 基类实现WebSocket服务端

接下来通过一个简单的多人实时聊天程序

首先了解下思路:

每个客户所用的浏览器都与服务器建立一个WebSocket,从而保持实时连接,这样客户端的浏览器可以随时把数据发送给服务器端;当服务器收到任何一个浏览器发来的消息,将该消息broadcast每个浏览器。

开发WebSocket服务端 步骤

1.定义@OnOpen修饰的方法:当每个客户端连接进来时来激发该方法,程序使用集合来保存所有连接进来的客户端

2.定义@OnMessage修饰的方法: 服务端接收浏览器消息激发该方法,服务端收到消息之后遍历保存客户端集合,并broadcast 所有浏览器

3.定义@OnClose修饰的方法,将该客户端从集合中删除;

服务器 代码:

@ServerEndpoint(value = "/websocket/chat")

public class ChatEntpoint {

private static final String GUEST_PREFIX = "访客";

private static final AtomicInteger connectionIds = new AtomicInteger(0);

// 定义一个集合,用于保存所有接入的WebSocket客户端

private static final Set<ChatEntpoint> clientSet = new CopyOnWriteArraySet<>();

// 定义一个成员变量,记录WebSocket客户端的聊天昵称

private final String nickname;

// 定义一个成员变量,记录与WebSocket之间的会话

private Session session;

public ChatEntpoint() {

nickname = GUEST_PREFIX + connectionIds.getAndIncrement();

}

// 当客户端连接进来时自动激发该方法

@OnOpen

public void start(Session session) {

this.session = session;

// 将WebSocket客户端会话添加到集合中

clientSet.add(this);

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

// 发送消息

broadcast(message);

System.out.println(message);

}

// 当客户端断开连接时自动激发该方法

@OnClose

public void end() {

clientSet.remove(this);

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

// 发送消息

broadcast(message);

System.out.println(message);

}

// 每当收到客户端消息时自动激发该方法

@OnMessage

public void incoming(String message) {

String filteredMessage = String.format("%s: %s", nickname,

filter(message));

// 发送消息

broadcast(filteredMessage);

System.out.println(filteredMessage);

}

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

@OnError

public void onError(Throwable t) throws Throwable {

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

}

// 实现广播消息的工具方法

private static void broadcast(String msg) {

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

for (ChatEntpoint client : clientSet) {

try {

synchronized (client) {

// 发送消息

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

}

} catch (IOException e) {

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

clientSet.remove(client);

try {

client.session.close();

} catch (IOException e1) {

}

String message = String.format("【%s %s】", client.nickname,

"已经被断开了连接。");

broadcast(message);

}

}

}

// 定义一个工具方法,用于对字符串中的HTML字符标签进行转义

private static String filter(String message) {

if (message == null)

return null;

char content[] = new char[message.length()];

message.getChars(0, message.length(), content, 0);

StringBuilder result = new StringBuilder(content.length + 50);

for (int i = 0; i < content.length; i++) {

// 控制对尖括号等特殊字符进行转义

switch (content[i]) {

case '<':

result.append("<");

break;

case '>':

result.append(">");

break;

case '&':

result.append("&");

break;

case '"':

result.append(""");

break;

default:

result.append(content[i]);

}

}

return (result.toString());

}

}

注:Tomcat 为每个WebSocket客户端创建一个ChatEntpoint 对象

客户端 chat.html代码 :

<!DOCTYPE html>

<html>

<head>

<meta name="author" content="http://blog.csdn.net/u014229282" />

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title> 使用WebSocket通信 </title>

<script type="text/javascript">

// 创建WebSocket对象

var webSocket = new WebSocket("ws://localhost:8080/WebSocket/websocket/chat");

var sendMsg = function()

{

var inputElement = document.getElementById('msg');

// 发送消息

webSocket.send(inputElement.value);

// 清空单行文本框

inputElement.value = "";

}

var send = function(event)

{

if (event.keyCode == 13)

{

sendMsg();

}

};

webSocket.onopen = function()

{

// 为onmessage事件绑定监听器,接收消息

webSocket.onmessage= function(event)

{

var show = document.getElementById('show')

// 接收、并显示消息

show.innerHTML += event.data + "<br/>";

show.scrollTop = show.scrollHeight;

}

document.getElementById('msg').onkeydown = send;

document.getElementById('sendBn').onclick = sendMsg;

};

webSocket.onclose = function ()

{

document.getElementById('msg').onkeydown = null;

document.getElementById('sendBn').onclick = null;

Console.log('WebSocket已经被关闭。');

};

</script>

</head>

<body>

<div style="width:600px;height:240px;

overflow-y:auto;border:1px solid #333;" id="show"></div>

<input type="text" size="80" id="msg" name="msg" placeholder="输入聊天内容"/>

<input type="button" value="发送" id="sendBn" name="sendBn"/>

</body>

</html>

注:WebSocket肯定会成为Web应用开发的主流技术,这种技术颠覆了传统Web应用请求/响应 架构模型,它可以让服务器与浏览器建立实时通信的Socket。为了使用WebSocket,还需要JavaScript 编程知识。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: