PHP8.1.21版本已发布
vue8.1.21版本已发布
jquery8.1.21版本已发布

HTML5基于Tomcat 7.0实现WebSocket连接并实现简单的实时聊天

高洛峰
高洛峰 原创
2016-12-08 13:37:05 1181浏览

1、什么是WebSocket?

WebSocket 是一种自然的全双工、双向、单套接字连接。使用WebSocket,你的HTTP 请求变成打开WebSocket 连接(WebSocket 或者WebSocket over TLS(TransportLayer Security,传输层安全性,原称“SSL”))的单一请求,并且重用从客户端到服务器以及服务器到客户端的同一连接。WebSocket 减少了延迟,因为一旦建立起WebSocket 连接,服务器可以在消息可用时发送它们。例如,和轮询不同,WebSocket只发出一个请求。服务器不需要等待来自客户端的请求。相似地,客户端可以在任何时候向服务器发送消息。相比轮询不管是否有可用消息,每隔一段时间都发送一个请求,单一请求大大减少了延迟。

2、WebSocket API

WebSocket API 使你可以通过Web,在客户端应用程序和服务器端进程之间建立全双工的双向通信。WebSocket 接口规定了可用于客户端的方法以及客户端与网络的交互方式。 

3、WebSocket构造函数

为了建立到服务器的WebSocket连接,使用WebSocket接口,通过指向一个代表所要连接端点的URL,实例化一个WebSocket对象。WebSocket 协议定义了两种URL方案(URL scheme)—ws和wss,分别用于客户端和服务器之间的非加密与加密流量。

实例:var ws = new WebSocket("ws://www.websocket.org");

4、WebSocket事件

WebSocket API 是纯事件驱动的。应用程序代码监听WebSocket对象上的事件,以便处理输入数据和连接状态的改变。WebSocket协议也是事件驱动的。

WebSocket对象调度4个不同的事件:

A、open事件:

一旦服务器响应了WebSocket连接请求,open事件触发并建立一个连接。open事件对应的回调函数称作onopen

实例:

ws.onopen = function(e) {
console.log("Connection open...");
};

   

B、messagess事件: 

message事件在接收到消息时触发,对应于该事件的回调函数是onmessage。 

实例:

ws.onmessage = function(e) {
if(typeof e.data === "string"){
console.log("String message received", e, e.data);
} else {
console.log("Other message received", e, e.data);
}
};

   

C、error事件:

error 事件在响应意外故障的时候触发。与该事件对应的回调函数为onerror。 
实例:

ws.onerror = function(e){
console.log('websocked error');
handerError();
}

   

D、close事件:

close 事件在WebSocket 连接关闭时触发。对应于close 事件的回调函数是onclose。

实例:

ws.onclose = function(e) {
console.log("Connection closed", e);
};

   

5、WebSocket方法

WebSocket 对象有两个方法:send() 和close()。

A、 send() 方法:

使用WebSocket在客户端和服务器之间建立全双工双向连接后,就可以在连接打开时调用send() 方法。使用send() 方法可以从客户端向服务器发送消息。在发送一条或者多条消息之后,可以保持连接打开,或者调用close() 方法终止连接。

实例:

ws.send("Hello WebSocket!");

   

B、close ()方法:

使用close()方法,可以关闭WebSocket连接或者终止连接尝试。如果连接已经关闭,该方法就什么都不做。在调用close()之后,不能在已经关闭的WebSocket上发送任何数据。可以向close()方法传递两个可选参数:code(数字型的状态代码)和reason(一个文本字符串)。传递这些参数能够向服务器传递关于客户关闭连接原因的信息。 

注:以上是对 WebSocket的简单介绍,下面将用一个简单的网页实时聊天案例来介绍如何使用WebSocket

A:首先新建一个项目我这里叫chatroom,在建一个包然后新建一个类用于实现服务器端的连接我的类名叫ChatWebSocketServlet.Java;

具体项目搭建如下图: 

 

B:写服务器端实现类ChatWebSocketServlet.java,具体代码如下:

package com.yc.chat.Servlet;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.StreamInbound;
import org.apache.catalina.websocket.WebSocketServlet;
import org.apache.catalina.websocket.WsOutbound;
@WebServlet("/chat")
public class ChatWebSocketServlet extends WebSocketServlet {
private final Map map = new HashMap();
private static final long serialVersionUID = -1058445282919079067L;
@Override
protected StreamInbound createWebSocketInbound(String arg0, HttpServletRequest request) {
// StreamInbound:基于流的WebSocket实现类(带内流),应用程序应当扩展这个类并实现其抽象方法onBinaryData和onTextData。
return new ChatMessageInbound();
}
class ChatMessageInbound extends MessageInbound {
// MessageInbound:基于消息的WebSocket实现类(带内消息),应用程序应当扩展这个类并实现其抽象方法onBinaryMessage和onTextMessage。
@Override
protected void onOpen(WsOutbound outbound) {
map.put(outbound.hashCode(), outbound);
super.onOpen(outbound);
}
@Override
protected void onClose(int status) {
map.remove(getWsOutbound().hashCode());
super.onClose(status);
}
@Override
protected void onBinaryMessage(ByteBuffer buffer) throws IOException {
}
@Override
protected void onTextMessage(CharBuffer buffer) throws IOException {
String msg = buffer.toString();
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
msg = " 匿名用戶 " + sdf.format(date) + "
 " + msg; broadcast(msg); } private void broadcast(String msg) { Set set = map.keySet(); for (Integer integer : set) { WsOutbound outbound = map.get(integer); CharBuffer buffer = CharBuffer.wrap(msg); try { outbound.writeTextMessage(buffer); outbound.flush(); } catch (IOException e) { e.printStackTrace(); } } } } }

   

C:实现前台页面index.jsp(为了展示功能并没有美化,比较简陋)具体代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>




websocket聊天室

#chat {
text-align: left;
width: 600px;
height: 500px;
width: 600px;
}
#up {
text-align: left;
width: 100%;
height: 400px;
border: 1px solid green;
OVERFLOW-Y: auto;
}
#down {
text-align: left;
height: 100px;
width: 100%;
}


基于HTML5的聊天室
 
var socket; var receive_text = document.getElementById("up"); var send_text = document.getElementById("send"); function addText(msg) { receive_text.innerHTML += "
" + msg; receive_text.scrollTop = receive_text.scrollHeight; } var chat = function(obj) { obj.disabled = "disabled"; socket = new WebSocket('ws://localhost:8080/chatroom/chat'); receive_text.innerHTML += "正在连接服务器……"; //打开Socket socket.onopen = function(event) { addText("连接成功!"); document.getElementById("send_btn").disabled = false; send_text.focus(); document.onkeydown = function(event) { if (event.keyCode == 13 && event.ctrlKey) { send(); } } }; socket.onmessage = function(event) { addText(event.data); }; socket.onclose = function(event) { addText("连接断开!"); obj.disabled = ""; }; if (socket == null) { addText("连接失败!"); } }; var send = function(obj) { if (send_text.value == "") { return; } socket.send(send_text.value); send_text.value = ""; send_text.focus(); }

   

这样一个简单的实时聊天页面就做好了,接下来将项目部署到Tomcat 7.0服务器,并开启服务器就可以实现聊天了

结果展示:

1.在地址栏输入服务器地址:

http://127.0.0.1:8080/chatroom/index.jsp

点击连接服务器结果如下:

201611011003251.png

2.分别在两个不同的浏览器打开并互相发送信息(我这里用谷歌和火狐)结果如下: 

201611011003251.png

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。