前言
HTML5 WebSocket实现了服务器与浏览器的双向通讯,双向通讯使服务器消息推送开发更加简单,最常见的就是即时通讯和对信息实时性要求比较高的应用。以前的服务器消息推送大部分采用的都是“轮询”和“长连接”技术,这两中技术都会对服务器产生相当大的开销,而且实时性不是特别高。WebSocket技术对只会产生很小的开销,并且实时性特别高。下面就开始讲解如何利用WebSocket技术开发聊天室。在这个实例中,采用的是Tomcat7服务器,每个服务器对于WebSocket的实现都是不一样的,所以这个实例只能在Tomcat服务器中运行,不过目前Spring已经推出了WebSocket的API,能够兼容各个服务器的实现,大家可以查阅相关的资料进行了解,在这里就不介绍了,下图是聊天室的效果图:
在这里实例中,实现了消息的实时推送,还实现了聊天用户的上下线通知。下面就开始具体讲解如何实现。
后台处理
Tomcat实现WebSocket的主要是依靠org.apache.catalina.websocket.MessageInbound这个类,这个类的在{TOMCAT_HOME}/lib/catalina.jar中,所以你开发的时候需要将catalina.jar和tomcat-coyote.jar引入进来,下面这段代码就是暴露给客户端连接地址的Servlet:
- package com.ibcio;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServletRequest;
- import org.apache.catalina.websocket.StreamInbound;
- @WebServlet(urlPatterns = { "/message"})
- //如果要接收浏览器的ws://协议的请求就必须实现WebSocketServlet这个类
- public class WebSocketMessageServlet extends org.apache.catalina.websocket.WebSocketServlet {
- private static final long serialVersionUID = 1L;
- public static int ONLINE_USER_COUNT = 1;
- public String getUser(HttpServletRequest request){
- return (String) request.getSession().getAttribute("user");
- }
- //跟平常Servlet不同的是,需要实现createWebSocketInbound,在这里初始化自定义的WebSocket连接对象
- @Override
- protected StreamInbound createWebSocketInbound(String subProtocol,HttpServletRequest request) {
- return new WebSocketMessageInbound(this.getUser(request));
- }
- }
- package com.ibcio;
- import java.io.IOException;
- import java.nio.ByteBuffer;
- import java.nio.CharBuffer;
- import net.sf.json.JSONObject;
- import org.apache.catalina.websocket.MessageInbound;
- import org.apache.catalina.websocket.WsOutbound;
- public class WebSocketMessageInbound extends MessageInbound {
- //当前连接的用户名称
- private final String user;
- public WebSocketMessageInbound(String user) {
- this.user = user;
- }
- public String getUser() {
- return this.user;
- }
- //建立连接的触发的事件
- @Override
- protected void onOpen(WsOutbound outbound) {
- // 触发连接事件,在连接池中添加连接
- JSONObject result = new JSONObject();
- result.element("type", "user_join");
- result.element("user", this.user);
- //向所有在线用户推送当前用户上线的消息
- WebSocketMessageInboundPool.sendMessage(result.toString());
- result = new JSONObject();
- result.element("type", "get_online_user");
- result.element("list", WebSocketMessageInboundPool.getOnlineUser());
- //向连接池添加当前的连接对象
- WebSocketMessageInboundPool.addMessageInbound(this);
- //向当前连接发送当前在线用户的列表
- WebSocketMessageInboundPool.sendMessageToUser(this.user, result.toString());
- }
- @Override
- protected void onClose(int status) {
- // 触发关闭事件,在连接池中移除连接
- WebSocketMessageInboundPool.removeMessageInbound(this);
- JSONObject result = new JSONObject();
- result.element("type", "user_leave");
- result.element("user", this.user);
- //向在线用户发送当前用户退出的消息
- WebSocketMessageInboundPool.sendMessage(result.toString());
- }
- @Override
- protected void onBinaryMessage(ByteBuffer message) throws IOException {
- throw new UnsupportedOperationException("Binary message not supported.");
- }
- //客户端发送消息到服务器时触发事件
- @Override
- protected void onTextMessage(CharBuffer message) throws IOException {
- //向所有在线用户发送消息
- WebSocketMessageInboundPool.sendMessage(message.toString());
- }
- }
代码中的主要实现了onOpen、onClose、onTextMessage方法,分别处理用户上线、下线、发送消息。在这个类中有个WebSocketMessageInboundPool连接池类,这个类是用来管理目前在线的用户的连接,下面是这个类的代码:
- package com.ibcio;
- import java.io.IOException;
- import java.nio.CharBuffer;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Set;
- public class WebSocketMessageInboundPool {
- //保存连接的MAP容器
- private static final Map<String,WebSocketMessageInbound > connections = new HashMap<String,WebSocketMessageInbound>();
- //向连接池中添加连接
- public static void addMessageInbound(WebSocketMessageInbound inbound){
- //添加连接
- System.out.println("user : " + inbound.getUser() + " join..");
- connections.put(inbound.getUser(), inbound);
- }
- //获取所有的在线用户
- public static Set<String> getOnlineUser(){
- return connections.keySet();
- }
- public static void removeMessageInbound(WebSocketMessageInbound inbound){
- //移除连接
- System.out.println("user : " + inbound.getUser() + " exit..");
- connections.remove(inbound.getUser());
- }
- public static void sendMessageToUser(String user,String message){
- try {
- //向特定的用户发送数据
- System.out.println("send message to user : " + user + " ,message content : " + message);
- WebSocketMessageInbound inbound = connections.get(user);
- if(inbound != null){
- inbound.getWsOutbound().writeTextMessage(CharBuffer.wrap(message));
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- //向所有的用户发送消息
- public static void sendMessage(String message){
- try {
- Set<String> keySet = connections.keySet();
- for (String key : keySet) {
- WebSocketMessageInbound inbound = connections.get(key);
- if(inbound != null){
- System.out.println("send message to user : " + key + " ,message content : " + message);
- inbound.getWsOutbound().writeTextMessage(CharBuffer.wrap(message));
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
前台展示
- <%@ page language="java" pageEncoding="UTF-8" import="com.ibcio.WebSocketMessageServlet"%>
- <%
- String user = (String)session.getAttribute("user");
- if(user == null){
- //为用户生成昵称
- user = "游客" + WebSocketMessageServlet.ONLINE_USER_COUNT;
- WebSocketMessageServlet.ONLINE_USER_COUNT ++;
- session.setAttribute("user", user);
- }
- pageContext.setAttribute("user", user);
- %>
- <html>
- <head>
- <title>WebSocket 聊天室</title>
- <!-- 引入CSS文件 -->
- <link rel="stylesheet" type="text/css" href="ext4/resources/css/ext-all.css">
- <link rel="stylesheet" type="text/css" href="ext4/shared/example.css" />
- <link rel="stylesheet" type="text/css" href="css/websocket.css" />
- <!-- 映入Ext的JS开发包,及自己实现的webscoket. -->
- <script type="text/javascript" src="ext4/ext-all-debug.js"></script>
- <script type="text/javascript" src="websocket.js"></script>
- <script type="text/javascript">
- var user = "${user}";
- </script>
- </head>
- <body>
- <h1>WebSocket聊天室</h1>
- <p>通过HTML5标准提供的API与Ext富客户端框架相结合起来,实现聊天室,有以下特点:</p>
- <ul class="feature-list" style="padding-left: 10px;">
- <li>实时获取数据,由服务器推送,实现即时通讯</li>
- <li>利用WebSocket完成数据通讯,区别于轮询,长连接等技术,节省服务器资源</li>
- <li>结合Ext进行页面展示</li>
- <li>用户上线下线通知</li>
- </ul>
- <div id="websocket_button"></div>
- </body>
- </html>
页面的展示主要是在websocket.js中进行控制,下面是websocket.jsd的代码:
相关推荐
本项目源码展示了如何使用Java进行WebSocket的整合,从而实现服务器消息推送功能。以下将详细介绍WebSocket的核心概念、Java整合WebSocket的步骤以及在实际项目中的应用。 1. WebSocket简介: WebSocket协议是HTML5...
在这个“基于WebSocket的web聊天室”项目中,我们将会探讨如何使用Java来实现一个实时的、交互式的聊天应用程序。 首先,我们需要理解WebSocket的工作原理。WebSocket协议基于TCP,它在HTTP握手之后建立连接,并...
WebSocket是一种在客户端和服务器之间建立长连接的协议,它允许双方进行双向通信,即服务器可以主动向客户端推送数据,而不仅仅是响应客户端的请求。在Java中实现WebSocket通信,我们可以使用Java API for WebSocket...
接下来我们关注基于Tomcat7、Java和WebSocket的服务器推送聊天室项目。Tomcat7是一个广泛使用的开源Java Servlet容器,支持包括WebSocket在内的多种Web技术。在Java中实现WebSocket,我们需要遵循JSR 356规范,该...
在这个项目中,“基于Tomcat8+Java7+ExtJS的WebSocket聊天室实现”利用了这些技术来创建一个实时交互的聊天应用。 1. **WebSocket简介** WebSocket为Web应用提供了低延迟、双向通信的能力,使得服务器能够主动向...
为了测试WebSocket功能,你可以创建一个简单的WebSocket应用,例如一个聊天室或实时推送通知。在Java中,你可以使用`javax.websocket`包提供的接口和类来创建WebSocket服务器端点和客户端。同时,你还需要确保客户端...
jsp WebSocket+Tomcat实现真●Web版即时聊天室(单人+多人),传统的web配置方式,方便移植到自己的系统里,功能包括单人聊天(点对点的推送),多人广播,大家有兴趣还可以自己扩展 这里是tomcat8基于注解的方式实现,...
WebSocket是Web应用中的一种协议,它实现了浏览器与服务器的全双工通信,即允许服务器主动向客户端推送数据。WebSocket协议的出现解决了HTTP协议下服务器无法主动推送数据的问题,极大地优化了实时性要求高的应用...
Java仿QQ聊天室基于WebSocket技术实现,是一种实时通信的应用,允许服务器与客户端之间进行双向通信。WebSocket协议在HTTP/1.1的基础上进行了扩展,提供了一种低延迟、高效率的实时交互方式,使得在线聊天应用如QQ的...
WebSocket 技术是一种在客户端和服务器之间建立长连接的协议,它使得实时、双向通信成为可能,非常适合构建实时交互的应用,比如聊天室。本项目利用WebSocket实现了一个基础的聊天功能,用户可以登录并进行交流。 ...
基于Tomcat7、Java、Ext、WebSocket的聊天室 个人测试环境:win10,java8,Tomcat7, 浏览器:火狐、Edge 部署访问:http://localhost:8080/WebSocket/index.jsp
在传统的HTTP协议中,客户端需要不断发起请求来获取服务器的新信息,而WebSocket则允许服务器在接收到新数据时主动推送给客户端,大大提升了实时性,非常适合于在线聊天、股票交易、游戏等需要实时交互的应用场景。...
6. **WebSocket**:如果聊天室实现了实时通信,可能使用了WebSocket协议,它提供了全双工的通信通道,使得服务器能主动向客户端推送数据。 7. **AJAX**:Asynchronous JavaScript and XML,一种在不刷新整个页面的...
- **WebSocket**:另一种可能实现的方式是使用WebSocket协议,它提供双向通信,允许服务器主动推送消息到客户端,相比AJAX轮询更加高效。 4. **数据库设计**: - **表结构**:数据库中可能有两张表,一张是用户...
与HTTP不同,WebSocket允许服务器主动向客户端推送数据,这对于实时聊天系统至关重要。Spring Boot提供了WebSocket的支持,开发者可以通过WebSocketStompEndpoint类来定义WebSocket端点,并结合...
7. **部署与运行**:Java Web应用通常部署在应用服务器上,如Tomcat、Jetty等,用户可以通过访问服务器的特定URL来启动聊天室。 通过分析这个源码,开发者不仅可以学习到如何构建一个实时聊天应用,还能深入理解...
本示例提供了基于JSP和Java的WebSocket实现,服务端使用了Tomcat作为应用服务器。Tomcat是一款开源的Servlet容器,广泛用于部署Java Web应用,包括JSP和Servlet。 首先,我们来看服务端的实现。在Java中,WebSocket...
在这里,可以采用发布/订阅模式,用户加入到特定的聊天室(频道),服务器将消息广播给所有订阅了该频道的用户。为了优化性能,可以使用Redis的发布/订阅功能,这样可以在内存中高效地分发消息,同时避免数据库的...
2. **服务器推送**:服务器不再被动等待客户端请求,而是能在有新数据时主动发送,适合实时应用如聊天室、股票行情等。 3. **节省资源**:相比于轮询或长轮询,WebSocket减少了不必要的网络请求,减轻了服务器负载。...