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


Posted in Javascript onOctober 31, 2016

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;

具体项目搭建如下图:

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

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<Integer, WsOutbound> map = new HashMap<Integer, WsOutbound>();
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 = " <font color=green>匿名用? " + sdf.format(date) + "</font><br/> " + msg;
broadcast(msg);
}
private void broadcast(String msg) {
Set<Integer> 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"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>websocket聊天室</title>
<style type="text/css">
#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%;
}
</style>
</head>
<body>
<h2 align="center">基于HTML5的聊天室</h2>
<div align="center" style="width: 100%; height: 700px;">
<div id="chat">
<div id="up"></div>
<div id="down">
<textarea type="text" style="width: 602px; height: 100%;" id="send"></textarea>
</div>
</div>
<input type="button" value="连接" onclick="chat(this);"> <input
type="button" value="发送" onclick="send(this);" disabled="disabled"
id="send_btn" title="Ctrl+Enter发送">
</div>
</body>
<script type="text/javascript">
var socket;
var receive_text = document.getElementById("up");
var send_text = document.getElementById("send");
function addText(msg) {
receive_text.innerHTML += "<br/>" + 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 += "<font color=green>正在连接服务器……</font>";
//打开Socket 
socket.onopen = function(event) {
addText("<font color=green>连接成功!</font>");
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("<font color=red>连接断开!</font>");
obj.disabled = "";
};
if (socket == null) {
addText("<font color=red>连接失败!</font>");
}
};
var send = function(obj) {
if (send_text.value == "") {
return;
}
socket.send(send_text.value);
send_text.value = "";
send_text.focus();
}
</script>
</html>

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

结果展示:

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

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

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

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

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

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

以上所述是小编给大家介绍的HTML5基于Tomcat 7.0实现WebSocket连接并实现简单的实时聊天,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
js 事件小结 表格区别
Aug 13 Javascript
JS 图片缩放效果代码
Jun 09 Javascript
基于JavaScript实现 获取鼠标点击位置坐标的方法
Apr 12 Javascript
javascript在IE下trim函数无法使用的解决方法
Sep 12 Javascript
每天一篇javascript学习小结(RegExp对象)
Nov 17 Javascript
浏览器环境下JavaScript脚本加载与执行探析之defer与async特性
Jan 14 Javascript
jQuery 选择同时包含两个class的元素的实现方法
Jun 01 Javascript
JS实现直接运行html代码的方法
Mar 13 Javascript
vue 将页面公用的头部组件化的方法
Dec 18 Javascript
vue .sync修饰符的使用详解
Jun 15 Javascript
高效jQuery选择器的5个技巧实例分析
Nov 26 jQuery
Vue绑定用户接口实现代码示例
Nov 04 Javascript
jQuery绑定事件的四种方式介绍
Oct 31 #Javascript
JS 实现导航菜单中的二级下拉菜单的几种方式
Oct 31 #Javascript
JS中作用域和变量提升(hoisting)的深入理解
Oct 31 #Javascript
jsp 网站引入外部css或者js失效问题解决
Oct 31 #Javascript
js学习笔记之事件处理模型
Oct 31 #Javascript
基于JS实现checkbox全选功能实例代码
Oct 31 #Javascript
新手学习前端之js模仿淘宝主页网站
Oct 31 #Javascript
You might like
曾在DC漫画界反派角色扮演的演员,谁才是你心目中的小丑之王?
2020/04/09 欧美动漫
PHP实现提取一个图像文件并在浏览器上显示的代码
2012/10/06 PHP
php 开发中加密的几种方法总结
2017/03/22 PHP
php设计模式之装饰模式应用案例详解
2019/06/17 PHP
基于PHP实现解密或加密Cloudflar邮箱保护
2020/06/24 PHP
在textarea文本域中显示HTML代码的方法
2007/03/06 Javascript
drag-and-drop实现图片浏览器预览
2015/08/06 Javascript
在Html中使用Requirejs进行模块化开发实例详解
2016/04/15 Javascript
JS实现获取剪贴板内容的方法
2016/06/21 Javascript
js自定义QQ菜单效果
2017/01/10 Javascript
Vuejs入门教程之Vue生命周期,数据,手动挂载,指令,过滤器
2017/04/19 Javascript
详解微信小程序Radio选中样式切换
2017/07/06 Javascript
js实现canvas图片与img图片的相互转换的示例
2017/08/31 Javascript
vue2.0.js的多级联动选择器实现方法
2018/02/09 Javascript
vue中的自定义分页插件组件的示例
2018/08/18 Javascript
Python3实战之爬虫抓取网易云音乐的热门评论
2017/10/09 Python
利用pandas进行大文件计数处理的方法
2018/07/25 Python
Mac下Anaconda的安装和使用教程
2018/11/29 Python
python实现关闭第三方窗口的方法
2019/06/28 Python
基于python的itchat库实现微信聊天机器人(推荐)
2019/10/29 Python
Python configparser模块配置文件过程解析
2020/03/03 Python
Python 忽略文件名编码的方法
2020/08/01 Python
python 怎样进行内存管理
2020/11/10 Python
python中if嵌套命令实例讲解
2021/02/25 Python
英国最大的户外商店:Go Outdoors
2019/04/17 全球购物
大四自我鉴定范文
2013/10/06 职场文书
高级技校毕业生自荐信
2013/11/18 职场文书
网络编辑职责
2014/03/01 职场文书
横幅标语大全
2014/06/17 职场文书
医学专业毕业生求职信
2014/06/20 职场文书
群众路线学习笔记范文
2014/11/06 职场文书
小石潭记导游词
2015/02/03 职场文书
婚宴祝酒词大全
2015/08/10 职场文书
解决Mysql的left join无效及使用的注意事项说明
2021/07/01 MySQL
vue中利用mqtt服务端实现即时通讯的步骤记录
2021/07/01 Vue.js
A22国内电台短波广播频率表
2022/05/10 无线电