`
redstarofsleep
  • 浏览: 443836 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

HTML5 WebSocket做聊天室(服务器端基于Jetty8)

阅读更多

早就厌倦了Ajax轮询,一直想试试Web Socket.这次终于体验了一把

 

这次用的浏览器是Chrome,IE不用提了,不支持,FireFox据说是支持的,但是实际试下来不支持.估计是有自己的API,下次再研究....(以上提到的浏览器都是最新稳定版Chrome15,IE9,Firefox8.0)

 

开发环境:Eclipse3.7,Jetty8.04

 

[2012/4/6日更新:Tomcat从7.0.27开始已经支持WebSocket了,http://www.iteye.com/news/24773]

 

先要说下在Eclipse中配置Jetty,这个着实花了一些时间.

首先,要先安装Jetty插件,不能在Server里搜索,如果直接点下图里的,自动搜到的Jetty插件只支持到6.而要支持Web Socket,Jetty至少要7.


所以,只能通过下面这URL手动安装Jetty插件:

http://download.eclipse.org/jetty/updates/jetty-wtp/development

 

在Eclipse里安装完Jetty插件后,就要按照Jetty了,Jetty其实不需要安装,下载下来就是一个压缩包,解压了就可以使用,但是不能放在含空格的路径下,比如放在program files目录下就不行,Eclipse里起Jetty就起不来.

 

还没完...,看一下Jetty的lib目录,里面除了Jar包,还有很多文件夹,这些文件夹里面还是Jar包.本来呢这也没什么,但是在Eclipse里就悲剧了,它认不出来,不知道是插件的问题还是Eclipse本身的问题.要解决这个问题就得把那些文件夹里的Jar包拷出来,直接放在Jetty的lib目录下.这样经过改装的Jetty,终于可以在Eclipse里启动了.

 

要使用WebSocket,光能在Eclipse中启动Jetty是不够的,还需要导入一个Jar包,把Jetty中lib下的jetty-websocket-8.0.4.v20111024.jar拷贝到项目的lib下.

 

这样子就有了2个Jetty,一个是直接解压出来的原版Jetty,如果要部署war包,就用这个.另一个是经过改装的,专用于Eclipse里调试.

 

真够麻烦的,Jetty终于搞定了.还是Tomcat方便,可惜Tomcat到7为止没有支持Web Socket.

 

搞定了Web服务器,现在可以开始写一些代码了.

 

顺着上面的,先来看服务器端的代码:

服务器端要提供Websocket就需要实现OnTextMessage,实现其中的三个方法:onOpen(),onMessage()和onClose().

onOpen在一个客户端连上来的时候调用

onClose在客户端断开时调用

onMessage在客户端发送消息时调用

 

除了这个Socket类之外,还需要一个Servlet来接收客户端请求,这个Servlet也不是传统的Servlet(要是传统的Servlet就可以用Tomcat咯),这个Servlet需要继承WebSocketServlet.

 

服务器端需要做的基本就这么多,接下来是前端HTML

与服务器端类似

首先需要实例化一个WebSocket对象,然后定义它的onOpen,onClose方法.需要发送消息时调用send方法.

 

下面,贴一下聊天室的代码:

首先有一个普通的Servlet执行初始化,主要是定义一个List,用户存放WebSocket对象:

public class InitServlet extends HttpServlet {

	private static final long serialVersionUID = -1936532122758235837L;
	
	private static List<MyWebSocket> socketList;
	
	public void init(ServletConfig config) throws ServletException {
		InitServlet.socketList = new ArrayList<MyWebSocket>();
		super.init(config);
		System.out.println("Server start============");
	}
	
	public static synchronized List<MyWebSocket> getSocketList() {
		return InitServlet.socketList;
	}

}

 然后写一个Servlet处理请求,这个Servlet就返回一个WebSocket对象:

public class MyWebSocketServlet extends WebSocketServlet {

	private static final long serialVersionUID = -7302427588920888589L;

	@Override
	public WebSocket doWebSocketConnect(HttpServletRequest request, String arg1) {
		return new MyWebSocket();
	}

}

 最后实现WebSocket,循环InitServlet中的List,给所有客户端发送消息:

public class MyWebSocket implements OnTextMessage {

	private Connection conn;

	/* (non-Javadoc)
	 * @see org.eclipse.jetty.websocket.WebSocket#onClose(int, java.lang.String)
	 * 一个客户端断开时,从List中移除
	 */
	@Override
	public void onClose(int arg0, String arg1) {
		InitServlet.getSocketList().remove(this);
		System.out.println("onClose==========================");
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jetty.websocket.WebSocket#onOpen(org.eclipse.jetty.websocket.WebSocket.Connection)
	 * 一个客户端连上来时,将它加入List
	 */
	@Override
	public void onOpen(Connection conn) {
		// 如果客户端在这个MaxIdleTime中都没有活动,则它会自动结束
		System.out.println("onOpen=========================="+conn.getMaxIdleTime());
		this.conn = conn;
		InitServlet.getSocketList().add(this);
	}
	
	
	/* (non-Javadoc)
	 * @see org.eclipse.jetty.websocket.WebSocket.OnTextMessage#onMessage(java.lang.String)
	 * 一个客户端发送数据后,触发它自己的onMessage方法,在这个方法里给所有在线的客户端发送这条消息
	 */
	@Override
	public void onMessage(String data) {
System.out.println("~~~~~~~~~~" + data);
		List<MyWebSocket> socketList = InitServlet.getSocketList();
		for (MyWebSocket socket : socketList) {
			try {
				socket.getConn().sendMessage(data);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}
	
	
	public Connection getConn() {
		return conn;
	}

	public void setConn(Connection conn) {
		this.conn = conn;
	}

}

 好,服务器端代码展示完毕,接下来是前端HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Chart</title>
<script type="text/javascript" src="../../js/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
var ws = null;
function startWebSocket() {
	if (!window.WebSocket) alert("WebSocket not supported by this browser!");
	// 创建WebSocket
	ws = new WebSocket("ws://localhost:8080/html5chart/mywebsocket.do");
	// 收到消息时在消息框内显示
	ws.onmessage = function(evt) {   
		$('#msgBox').append(evt.data);
		$('#msgBox').append('</br>');
	};
	// 断开时会走这个方法
	ws.onclose = function() { 
		alert('close~~~~~~~');
	};
	// 连接上时走这个方法
	ws.onopen = function() {   
		alert('open~~~~~~~~'); 
	};
}
  
// 发送消息
function sendMsg() {
	var data = document.getElementById('msgSendBox').value;
	ws.send(data);
	document.getElementById('msgSendBox').value = '';
	
}
</script>
</head>
<body onload="startWebSocket();">
<div id="msgBox" style="width:400px;height:300px;border:1px solid #000000">
</div>
<textarea id="msgSendBox" rows="5" cols="32"></textarea>
<input type="button" value="send" onclick="sendMsg()"></input>
</body>
</html>

 

最后附上web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>html5test</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
 
  <servlet>
    <servlet-name>initServlet</servlet-name>
    <servlet-class>lhc.init.InitServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet>
  	<servlet-name>mywebsocket</servlet-name>
  	<servlet-class>lhc.websocket.MyWebSocketServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>mywebsocket</servlet-name>
  	<url-pattern>*.do</url-pattern>
  </servlet-mapping>
</web-app>

 

至此,一个具有基础功能的基于HTML5 Web Socket的简陋聊天室就做完了.

 

  • 大小: 82 KB
7
4
分享到:
评论
21 楼 redstarofsleep 2014-07-22  
赤道螞蟻 写道
如果是數據庫有定時任務,定時更新表的數據。 表中數據變化時,主動發消息給web頁面, 該怎麼做呢??

调用第一段代码里的public static synchronized List<MyWebSocket> getSocketList()方法.
然后就可以getConn,再sendMessage
20 楼 赤道螞蟻 2014-07-22  
如果是數據庫有定時任務,定時更新表的數據。 表中數據變化時,主動發消息給web頁面, 該怎麼做呢??
19 楼 心的旅程 2013-03-14  
楼主呀,我的在火狐里运行也是光弹close ,后台也报错了,不知道怎么改
18 楼 yangf2008 2012-09-20  
redstarofsleep 写道
nickldq 写道
楼主 出现 无法建立到ws://localhost:8080/jetty/mywebscket.do服务器的连接的错误
报错显示在new websocket()这里

你是页面报错还是后台报错啊


你好LZ,new websocket() 后太有错:
java.lang.NullPointerException at
org.eclipse.jetty.websocket.WebSocketFactory.upgrade(WebSocketFactory.java:215)
请帮忙解答,谢谢
17 楼 redstarofsleep 2012-08-27  
小花_理想 写道
redstarofsleep 写道
小花_理想 写道
redstarofsleep 写道
小花_理想 写道
请问:我的工程用eclipse中的插件去启动jetty,运行正常。而把工程打包成war之后,部署到jetty服务器后,每次一建立连接就显示与websocket连接断开呢,都显示close~~~~~。求解答

jetty是什么版本的呢?


是jetty8.1.5

后台有报错吗


我用jetty8.04版本来作test,打成war包,运行时没有报错。
用eclipse插件启动时,握手协议时这样的:
Request URL:ws://localhost:8080/jetty/aa.do
Request Method:GET
Status Code:101 Switching Protocols
Request Headersview source
Connection:Upgrade
Host:localhost:8080
Origin:http://localhost:8080
Sec-WebSocket-Extensions:x-webkit-deflate-frame
Sec-WebSocket-Key:IZSDhv0ZAy42/J3aFXV/cg==
Sec-WebSocket-Version:13
Upgrade:websocket
(Key3):00:00:00:00:00:00:00:00
Response Headersview source
Connection:Upgrade
Sec-WebSocket-Accept:ITVdBt/V9b/j9soMSuUyOiQcm/U=
Upgrade:WebSocket
(Challenge Response):00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00

打成war之后,握手协议时这样的:
Request URL:ws://localhost:8080/jetty/aa.do
Request Headersview source
Connection:Upgrade
Host:localhost:8080
Origin:http://localhost:8080
Sec-WebSocket-Extensions:x-webkit-deflate-frame
Sec-WebSocket-Key:pToY0u0aYVFz2CdjCQfmLA==
Sec-WebSocket-Version:13
Upgrade:websocket
(Key3):00:00:00:00:00:00:00:00

是不是Sec-WebSocket-Key这里的问题?

后面的少了些东西?
Request Method:GET
Status Code:101 Switching Protocols
Request Headersview source
16 楼 小花_理想 2012-08-26  
redstarofsleep 写道
小花_理想 写道
redstarofsleep 写道
小花_理想 写道
请问:我的工程用eclipse中的插件去启动jetty,运行正常。而把工程打包成war之后,部署到jetty服务器后,每次一建立连接就显示与websocket连接断开呢,都显示close~~~~~。求解答

jetty是什么版本的呢?


是jetty8.1.5

后台有报错吗


我用jetty8.04版本来作test,打成war包,运行时没有报错。
用eclipse插件启动时,握手协议时这样的:
Request URL:ws://localhost:8080/jetty/aa.do
Request Method:GET
Status Code:101 Switching Protocols
Request Headersview source
Connection:Upgrade
Host:localhost:8080
Origin:http://localhost:8080
Sec-WebSocket-Extensions:x-webkit-deflate-frame
Sec-WebSocket-Key:IZSDhv0ZAy42/J3aFXV/cg==
Sec-WebSocket-Version:13
Upgrade:websocket
(Key3):00:00:00:00:00:00:00:00
Response Headersview source
Connection:Upgrade
Sec-WebSocket-Accept:ITVdBt/V9b/j9soMSuUyOiQcm/U=
Upgrade:WebSocket
(Challenge Response):00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00

打成war之后,握手协议时这样的:
Request URL:ws://localhost:8080/jetty/aa.do
Request Headersview source
Connection:Upgrade
Host:localhost:8080
Origin:http://localhost:8080
Sec-WebSocket-Extensions:x-webkit-deflate-frame
Sec-WebSocket-Key:pToY0u0aYVFz2CdjCQfmLA==
Sec-WebSocket-Version:13
Upgrade:websocket
(Key3):00:00:00:00:00:00:00:00

是不是Sec-WebSocket-Key这里的问题?
15 楼 redstarofsleep 2012-08-24  
小花_理想 写道
redstarofsleep 写道
小花_理想 写道
请问:我的工程用eclipse中的插件去启动jetty,运行正常。而把工程打包成war之后,部署到jetty服务器后,每次一建立连接就显示与websocket连接断开呢,都显示close~~~~~。求解答

jetty是什么版本的呢?


是jetty8.1.5

后台有报错吗
14 楼 蒹葭从风 2012-08-24  
小花_理想 写道
请问:我的工程用eclipse中的插件去启动jetty,运行正常。而把工程打包成war之后,部署到jetty服务器后,每次一建立连接就显示与websocket连接断开呢,都显示close~~~~~。求解答


同样的问题
13 楼 小花_理想 2012-08-24  
redstarofsleep 写道
小花_理想 写道
请问:我的工程用eclipse中的插件去启动jetty,运行正常。而把工程打包成war之后,部署到jetty服务器后,每次一建立连接就显示与websocket连接断开呢,都显示close~~~~~。求解答

jetty是什么版本的呢?


是jetty8.1.5
12 楼 redstarofsleep 2012-08-24  
小花_理想 写道
请问:我的工程用eclipse中的插件去启动jetty,运行正常。而把工程打包成war之后,部署到jetty服务器后,每次一建立连接就显示与websocket连接断开呢,都显示close~~~~~。求解答

jetty是什么版本的呢?
11 楼 小花_理想 2012-08-24  
请问:我的工程用eclipse中的插件去启动jetty,运行正常。而把工程打包成war之后,部署到jetty服务器后,每次一建立连接就显示与websocket连接断开呢,都显示close~~~~~。求解答
10 楼 蒹葭从风 2012-08-23  
redstarofsleep 写道
蒹葭从风 写道
Firefox 无法建立到 ws://localhost:8080/cometLongPolling/MyWebSocket 服务器的连接。


ws = new WebSocket("ws://localhost:8080/cometLongPolling/MyWebSocket");

每次打开都是alert出close~~~

这个是什么原因呢?

Firefox是:new MozWebSocket("");
在另一篇里有提到:http://redstarofsleep.iteye.com/blog/1488639

可以留下你的联系方式吗,这样可以方便交流一下,我的QQ429256840,方便的话加一下,谢谢
9 楼 redstarofsleep 2012-08-23  
蒹葭从风 写道
Firefox 无法建立到 ws://localhost:8080/cometLongPolling/MyWebSocket 服务器的连接。


ws = new WebSocket("ws://localhost:8080/cometLongPolling/MyWebSocket");

每次打开都是alert出close~~~

这个是什么原因呢?

Firefox是:new MozWebSocket("");
在另一篇里有提到:http://redstarofsleep.iteye.com/blog/1488639
8 楼 蒹葭从风 2012-08-23  
Firefox 无法建立到 ws://localhost:8080/cometLongPolling/MyWebSocket 服务器的连接。


ws = new WebSocket("ws://localhost:8080/cometLongPolling/MyWebSocket");

每次打开都是alert出close~~~

这个是什么原因呢?
7 楼 redstarofsleep 2012-08-07  
nickldq 写道
楼主 出现 无法建立到ws://localhost:8080/jetty/mywebscket.do服务器的连接的错误
报错显示在new websocket()这里

你是页面报错还是后台报错啊
6 楼 nickldq 2012-08-06  
楼主 出现 无法建立到ws://localhost:8080/jetty/mywebscket.do服务器的连接的错误
报错显示在new websocket()这里
5 楼 magicsa 2012-06-25  
你好博主,请问若是服务器广播文件过来,客户端的html代码(或javascript)该如何编写呢?

谢谢
4 楼 redstarofsleep 2012-01-18  
wxz859681117 写道
根据你的方法,始终没能前后台连接上,能否给个示例工程,多谢啦!邮箱:wxz859681117@yahoo.com.cn

这个工程所有的代码我都贴上来了啊....你哪里报错吗?
3 楼 wxz859681117 2012-01-18  
根据你的方法,始终没能前后台连接上,能否给个示例工程,多谢啦!邮箱:wxz859681117@yahoo.com.cn
2 楼 redstarofsleep 2011-12-13  
JetMah 写道

Firefox中是:window.MozWebSocket

多谢,我试试

相关推荐

    java WebSocket 聊天室 demo

    - 为了运行这个WebSocket聊天室 demo,你需要一个支持WebSocket的服务器环境,如Tomcat或Jetty。 - 部署Java WebSocket服务器端,并确保客户端(`chat.html`)能够访问到服务器。 - 使用多个浏览器实例或者模拟器...

    java实现基于websocket的聊天室

    WebSocket是Web交互技术的一种,它允许...以上就是基于Java实现WebSocket聊天室所需的关键技术和步骤。在实际开发过程中,还可能涉及到日志记录、异常处理、数据序列化等其他方面,都需要根据具体需求进行适配和扩展。

    Java WebSocket 多人聊天室Deomo

    在这个"Java WebSocket 多人聊天室Demo"中,我们可以学习到如何使用Java来构建一个基本的WebSocket聊天系统。 首先,我们需要创建WebSocket端点类。这个类继承自`javax.websocket.Endpoint`,并使用`@...

    websocket聊天室demo

    在这个"WebSocket聊天室demo"项目中,开发者手工编写了代码,确保了其原创性和适应性,已经在IE11、Firefox和Chrome等主流浏览器上进行了兼容性测试并成功运行。 WebSocket协议的核心概念: 1. **握手(Handshake)...

    websocket在线聊天室Demo

    WebSocket在线聊天室Demo是一个基于WebSocket技术实现的实时通信示例,它允许用户在网页上进行实时的双向通信,实现类似即时通讯应用的功能。WebSocket是一种在客户端和服务器之间建立长连接的协议,相比于传统的...

    基于websocket的聊天室.zip

    在这个"基于WebSocket的聊天室"项目中,我们将探讨如何使用WebSocket技术和相关编程语言如Java来创建一个实时的在线聊天应用程序。 WebSocket协议是HTML5的一部分,它通过TCP连接提供低延迟、高效率的双向通信。相...

    websocket 多人聊天室 网页版

    在构建多人聊天室时,开发者通常会利用Java的WebSocket API来处理服务器端的逻辑。Java的WebSocket API是在Java EE 7标准中引入的,它提供了`javax.websocket`包,包含ServerEndpoint、ClientEndpoint、...

    h5聊天室(websocket实现)

    1. **服务器端**:使用如Node.js、Java的WebSocket库(如Socket.IO或Jetty WebSocket)来处理WebSocket连接,接收并发送消息。 2. **客户端**:在HTML5的JavaScript中使用WebSocket对象建立连接,并处理发送和接收的...

    websocket简易聊天室

    5. **服务器端实现**:服务器端通常使用专门的WebSocket库来处理连接和数据交换,例如Node.js中的ws库,Java中的Jetty或Tomcat WebSocket支持,Python的SockJS-Tornado等。 6. **客户端实现**:在浏览器端,...

    java实现websocket聊天室

    在这个Java实现的WebSocket聊天室项目中,我们将探讨如何构建一个基本的聊天系统,支持私聊功能,并实现心跳包机制。 首先,我们需要了解WebSocket的基本原理。WebSocket协议基于TCP,它通过HTTP/1.1的Upgrade头来...

    H5实现websocket聊天对话

    - 后端:服务器端需要处理WebSocket连接,接收并分发消息,可能使用Node.js的ws库或者Java的Jetty WebSocket API等。 4. 聊天功能实现: - 用户注册/登录:通常通过HTTP/HTTPS完成,获取用户身份标识。 - 聊天室...

    WebSocket 聊天室 demo

    综上所述,“WebSocket 聊天室 demo”是一个展示WebSocket实时通信能力的示例项目,它涵盖了从客户端到服务器端的完整交互流程,以及如何构建一个实时、互动的在线聊天环境。通过学习和分析这个demo,开发者可以深入...

    websocket客户端和服务器端

    - **服务器端**:服务器端实现可以选择多种编程语言,如Node.js的ws库、Java的Jetty或Tomcat WebSocket API、Python的Tornado框架等。服务器端同样需要处理连接建立、数据接收、发送和关闭等逻辑。 在部署WebSocket...

    WebSocket实现一个简单的聊天室以及单聊功能

    WebSocket是一种在客户端和...在Java中,利用`javax.websocket`库,结合适当的服务器端和客户端逻辑,可以轻松实现聊天室和单聊功能。这个项目提供了一个很好的学习示例,帮助开发者掌握WebSocket在实际应用中的使用。

    websocket 聊天室

    在“WebSocket聊天室”项目中,我们主要关注以下几个核心知识点: 1. **WebSocket协议**:WebSocket协议是HTML5的一个重要特性,它解决了HTTP协议存在的不足,比如HTTP协议的每次请求都需要建立新的连接,而...

    java websocket实现简单的聊天功能

    总结来说,实现Java WebSocket聊天功能主要涉及以下几个步骤: 1. 创建WebSocket服务器端点类,实现`Endpoint`接口及其回调方法。 2. 在服务器端处理连接、消息、关闭和错误事件。 3. 创建WebSocket客户端,连接到...

    WebSocket网页实时聊天

    2. **后端实现**:在服务器端,如Java环境下,可以使用WebSocket库(如Jetty、Tomcat 7及以上版本内置的WebSocket支持)来处理连接和消息。例如,在Tomcat中,你需要创建一个实现了`javax.websocket.Endpoint`接口的...

    webSocket+java实现即时通讯聊天室,可直接导入运行

    导入项目后,运行服务器端的启动类,然后在浏览器中打开对应的HTML文件,就可以看到聊天室并测试即时通讯功能了。 总的来说,这个项目提供了一个实际操作WebSocket和Java即时通讯的示例,对于学习和理解WebSocket的...

    java仿QQ聊天室(websocket)

    Java仿QQ聊天室基于WebSocket技术实现,是一种实时通信的应用,允许服务器与客户端之间进行双向通信。WebSocket协议在HTTP/1.1的基础上进行了扩展,提供了一种低延迟、高效率的实时交互方式,使得在线聊天应用如QQ的...

    websocket单点聊天群聊

    服务器需要维护聊天室的概念,每个聊天室包含一组成员的WebSocket连接。当有新消息时,服务器会遍历该聊天室的成员列表,将消息分发给每个成员。为了处理成员的加入和退出,服务器需要提供相应的接口,用于创建、...

Global site tag (gtag.js) - Google Analytics