Java、WebSocket、HTML简易聊天室
2016-12-30 17:45
369 查看
WebSockt协议是一种双向通信的解决方案,减少了频繁建立连接所带来的开销,使得客户端和服务端的通信更加及时。与轮询(polling)和(Comet)技术相比,WebSockt在双端通信上有明显的优势。本文以Java、Tomcat、JavaScript实现双端通信实例。
本文所使用开发环境:Java 1.8.0_45、Tomcat 7.0.53、IDE IntelliJ IDEA 2016.3.1。开发环境搭建与项目配置方法不在本文讨论范围之内。
在进行项目开发之前,首先需要弄清楚一些基本概念,首先是WebSocket中的数据传输存在的数据有两种形式:控制帧(control
frame)和数据帧(data frame)。
控制帧又分为:关闭帧(close frame) 和ping-pong帧(ping and pong frames)
close frame:用于关闭连接
ping and pong frames:用于检测连接情况(是协议自带的心跳检测)
数据帧又主要有文本帧(textual frame)、字节帧(binary frame)
textual frame:接收客户端以文本形式传递的数据
binary frame:接收客户端以二进制形式传递的数据
控制帧一般是协议自己控制和实现的操作,我们在开发中并不需要自己实现。数据帧中的文本帧是最常用的,一般可以传递格式化的字符串数据,如json、xml等。字节帧接收的数据一般经过压缩处理,如gzip、prorobuf。其实数据帧除了这两种常见类型以外,还有一种partial
frame,一般用于传输大量数据,例如图片和视频。
在开发过程中,我们需要了解在WebSockt的生命周期中存在四种主要的事件:
The open event:建立连接事件
The message event:接收消息事件
The error event:连接或终端出错事件
The close event:关闭连接事件
了解了WebSocket的基本的概念以后,接着来看一下Java WebSocket的API,首先是EndPoint类的源码:
紧接着在看一下继承EndPoint类实现终端接口的ProgrammaticEchoServer类代码:
注意:EndPoint类是没有定义message event事件的处理的,此处的message event事件响应是在onOpen方法中给Session对象添加addMessageHandler方法添加的。在实现的onMessge中,只是将接收到的字符串加工一下就直接返回给另一个终端了。
接下来我们看一下另一个终端,HTML端JavaScript部分的相关代码:
首先建立WebSocket连接,建立连接以后客户端可以向服务终端发送字符串,服务端接收到以后,加工一下,直接返回,在将加工后的字符串显示在浏览器窗口。本页面的运行效果如下:
本实例只是单纯地收发消息并显示咋在浏览器窗口上,实现了双端的收发,和及时通信的骨架代码。接下来我们看一下本实例中的聊天室实例。
聊天室代码的Java终端是使用注解实现的,具体代码如下:
注意:@OnServerEndPoint注解表示该类为实现了EndPoint的终端,后面的参数表示在发布的项目该终端的相对路径。@OnOpen注解在此处仅接受一个Session参数,但是添加了@OnOpen注解的方法最多可以有三个参数:Session
session, EndPointConfig cfg, String parameters,而且这三个参数是可选无序的。后面的@OnMessage,@OnClose,@OnError注解也有这样的特性。
OK~~~代码中接受到消息后,会将消息发给每一个消息给广播给每一个连接中的每一个终端。
注意:每一个终端连接创建一个EndPoint对象,一个Session代表一次会话,因此需要在创建连接以后,将Session对象存储到一个全局单例的对象中,这就是最简易的连接池。
聊天室的运行效果如下:
最后附上实例代码:https://github.com/BruceT2010/WS-Samples
本文所使用开发环境:Java 1.8.0_45、Tomcat 7.0.53、IDE IntelliJ IDEA 2016.3.1。开发环境搭建与项目配置方法不在本文讨论范围之内。
在进行项目开发之前,首先需要弄清楚一些基本概念,首先是WebSocket中的数据传输存在的数据有两种形式:控制帧(control
frame)和数据帧(data frame)。
控制帧又分为:关闭帧(close frame) 和ping-pong帧(ping and pong frames)
close frame:用于关闭连接
ping and pong frames:用于检测连接情况(是协议自带的心跳检测)
数据帧又主要有文本帧(textual frame)、字节帧(binary frame)
textual frame:接收客户端以文本形式传递的数据
binary frame:接收客户端以二进制形式传递的数据
控制帧一般是协议自己控制和实现的操作,我们在开发中并不需要自己实现。数据帧中的文本帧是最常用的,一般可以传递格式化的字符串数据,如json、xml等。字节帧接收的数据一般经过压缩处理,如gzip、prorobuf。其实数据帧除了这两种常见类型以外,还有一种partial
frame,一般用于传输大量数据,例如图片和视频。
在开发过程中,我们需要了解在WebSockt的生命周期中存在四种主要的事件:
The open event:建立连接事件
The message event:接收消息事件
The error event:连接或终端出错事件
The close event:关闭连接事件
了解了WebSocket的基本的概念以后,接着来看一下Java WebSocket的API,首先是EndPoint类的源码:
public abstract class Endpoint { public Endpoint() { } public abstract void onOpen(Session var1, EndpointConfig var2); public void onClose(Session session, CloseReason closeReason) { } public void onError(Session session, Throwable throwable) { } }
紧接着在看一下继承EndPoint类实现终端接口的ProgrammaticEchoServer类代码:
public class ProgrammaticEchoServer extends Endpoint { @Override public void onOpen(Session session, EndpointConfig endpointConfig) { Session mySession = session; mySession.addMessageHandler(new MessageHandler.Whole<String>() { @Override public void onMessage(String text) { try { mySession.getBasicRemote().sendText("I got (" + text + ")" + "so I am send the message back.anna"); } catch (IOException e) { System.out.println("oh dear, something was wrong send the message back:" + e.getMessage()); } } }); } @Override public void onClose(Session session, CloseReason closeReason) { super.onClose(session, closeReason); } @Override public void onError(Session session, Throwable throwable) { super.onError(session, throwable); } }
注意:EndPoint类是没有定义message event事件的处理的,此处的message event事件响应是在onOpen方法中给Session对象添加addMessageHandler方法添加的。在实现的onMessge中,只是将接收到的字符串加工一下就直接返回给另一个终端了。
接下来我们看一下另一个终端,HTML端JavaScript部分的相关代码:
function initConnect() { //var wsUri = "ws://localhost:8080/programmaticEcho"; var wsUri = "ws://localhost:8080/echo"; writeToScreen("Connecting to " + wsUri); echo_websocket = new WebSocket(wsUri); echo_websocket.onopen = function (evt) { writeToScreen("Connected !"); }; echo_websocket.onmessage = function (evt) { writeToScreen("Received message: " + evt.data); }; echo_websocket.onerror = function (evt) { writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data); }; } function send_echo() { doSend(textID.value); } function doSend(message) { echo_websocket.send(message); writeToScreen("Sent message: " + message); }
首先建立WebSocket连接,建立连接以后客户端可以向服务终端发送字符串,服务端接收到以后,加工一下,直接返回,在将加工后的字符串显示在浏览器窗口。本页面的运行效果如下:
本实例只是单纯地收发消息并显示咋在浏览器窗口上,实现了双端的收发,和及时通信的骨架代码。接下来我们看一下本实例中的聊天室实例。
聊天室代码的Java终端是使用注解实现的,具体代码如下:
@ServerEndpoint("/chatroom") public class ChatRoom { private Session session; private List<String> names = new ArrayList<>(); private String username; @OnOpen public void open(Session session) { this.username = "用户-->" + session.getId(); this.session = session; SocketConfig.getInstance().add(this); names.add(username); broadCast(username + " 进入聊天室!!"); } @OnMessage public void receive(Session session, String msg) { broadCast(username + ":" + new Date().toString() + msg); } @OnClose public void close(Session session) { SocketConfig.getInstance().remove(this); names.remove(username); broadCast(username + " 退出聊天室!!"); } public void broadCast(String msg) { Set<ChatRoom> sockets = SocketConfig.getInstance().getSockets(); System.out.println("sockets-->" + sockets.size()); for (Iterator iterator = sockets.iterator(); iterator.hasNext(); ) { try { ChatRoom chatRoom = (ChatRoom) iterator.next(); chatRoom.session.getBasicRemote().sendText(msg); } catch (IOException e) { e.printStackTrace(); } } } }
注意:@OnServerEndPoint注解表示该类为实现了EndPoint的终端,后面的参数表示在发布的项目该终端的相对路径。@OnOpen注解在此处仅接受一个Session参数,但是添加了@OnOpen注解的方法最多可以有三个参数:Session
session, EndPointConfig cfg, String parameters,而且这三个参数是可选无序的。后面的@OnMessage,@OnClose,@OnError注解也有这样的特性。
OK~~~代码中接受到消息后,会将消息发给每一个消息给广播给每一个连接中的每一个终端。
注意:每一个终端连接创建一个EndPoint对象,一个Session代表一次会话,因此需要在创建连接以后,将Session对象存储到一个全局单例的对象中,这就是最简易的连接池。
聊天室的运行效果如下:
最后附上实例代码:https://github.com/BruceT2010/WS-Samples
相关文章推荐
- 基于 Java 和 jQuery 的简易聊天室
- 基于Tomcat7、Java、WebSocket的服务器推送聊天室
- 基于spring4 websocket的简易聊天室
- 基于Tomcat7、Java、WebSocket的服务器推送聊天室
- 基于Tomcat7、Java、WebSocket的服务器推送聊天室
- Java简易聊天室
- JAVA--简易聊天室程序
- Java基于socket实现简易聊天室实例
- 使用go,基于martini,和websocket开发简易聊天室
- 利用html 5 websocket做个山寨版web聊天室(手写C#服务器)
- 基于Tomcat7、Java、WebSocket的服务器推送聊天室
- 基于Tomcat7、Java、WebSocket的服务器推送聊天室项目
- node.js+websocket实现简易聊天室
- 基于Tomcat7、Java、WebSocket的服务器推送聊天室项目
- Java简易聊天室程序socket
- 【转载】Node.js + WebSocket 实现的简易聊天室
- 利用html 5 websocket做个山寨版web聊天室(手写C#服务器)
- 基于Tomcat7、Java、WebSocket的服务器推送聊天室
- 基于Tomcat7、Java、WebSocket的服务器推送聊天室
- 基于订阅/发布模式的简易聊天室实现(java+redis)