java web xmpp_WebSocket集成XMPP网页即时通讯1:Java Web Project服务端/客户端Jetty9开发初探...

Web 应用的信息交互过程通常是客户端通过浏览器发出一个请求,服务器端接收和审核完请求后进行处理并返回结果给客户端,然后客户端浏览器将信息呈现出来,这种机制对于信息变化不是特别频繁的应用尚能相安无事,但是对于那些实时要求比较高的应用来说,比如说在线游戏、在线证券、设备监控、新闻在线播报、RSS 订阅推送等等,当客户端浏览器准备呈现这些信息的时候,这些信息在服务器端可能已经过时了。所以保持客户端和服务器端的信息同步是实时 Web 应用的关键要素,对 Web 开发人员来说也是一个难题。在 WebSocket 规范出来之前,开发人员想实现这些实时的 Web 应用,不得不采用一些折衷的方案,其中最常用的就是轮询 (Polling) 和 Comet 技术(AJAX)。

但AJAX有显著缺点:

1、浏览器需要不断的向服务器发出请求,然而HTTP request 的header是非常长的,里面包含的有用数据可能只是一个很小的值,这样会占用很多的带宽。

2、客户端和服务器端的编程实现都比较复杂,在实际的应用中,为了模拟比较真实的实时效果,开发人员往往需要构造两个 HTTP 连接来模拟客户端和服务器之间的双向通讯,一个连接用来处理客户端到服务器端的数据传输,一个连接用来处理服务器端到客户端的数据传输。

WebSocket API是下一代客户端-服务器的异步通信方法。该通信取代了单个的TCP套接字,使用ws或wss(ssl加密)协议,可用于任意的客户端和服务器程序。WebSocket目前由W3C进行标准化。WebSocket已经受到Firefox 4、Chrome 4、Opera 10.70、Edge以及Safari 5等浏览器的支持。

WebSocket API最伟大之处在于服务器和客户端可以在给定的时间范围内(IdleTime)的任意时刻,相互推送信息。WebSocket并不限于以Ajax(或XHR)方式通信,因为Ajax技术需要客户端发起请求,而WebSocket服务器和客户端可以彼此相互推送信息;XHR受到域的限制,而WebSocket允许跨域通信。

为方便开发,用了Jetty服务器,在网上很多例子都是基于jetty7.0的。但jetty9.0以后WebSocket的基类代码变化很多,于是自己动手开发,参考jetty官网:

http://www.eclipse.org/jetty/documentation/current/websocket-jetty.html#jetty-websocket-api

首先在Eclipse新建一个Dynamic web project

请自行下载安装jetty,另外需要在Eclipse安装Jetty工具,便于调试。

e19b3678d82acb2c683d056312b70aba.png

工程目录结构:

d9aa1b96072def252162fe1f2a6a7347.png

web.xml

debug

false

10

MyServlet

MyServlet

MyServlet

/wsexample

index.html

index.htm

index.jsp

default.html

default.htm

default.jsp

ant用惯了,懒得去查maven的dependencies了。

build.xml

jetty.lib.dir、deploy.path请自行修改

Compilation completed

Archive created

Cleaning completed

Archive deployed

index.html

你好!websocket

index.js

var ws = new WebSocket("ws://localhost:8080/ws/wsexample");

ws.onopen= function() {

document.write("WebSocket opened
");

ws.send("Hello Server");

};

ws.onmessage= function(evt) {

document.write("Message: " +evt.data);

};

ws.onclose= function() {

document.write("
WebSocket closed");

};

ws.οnerrοr= function(err) {

document.write("Error: " +err);

};

其中 ws://localhost:8080/ws/wsexample 是WebSocket 服务器地址,是服务器端的Servelt,通过MyServlet.java实现

WebSocketServlet 类中configure(WebSocketServletFactory factory) 用来注册socket处理类和设置连接时长,在这个时长内,保持长连接。

MyServlet.java

暂不理会HTTP GET请求的处理.

importjava.io.IOException;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjavax.servlet.annotation.WebServlet;importorg.eclipse.jetty.websocket.servlet.WebSocketServlet;importorg.eclipse.jetty.websocket.servlet.WebSocketServletFactory;

@WebServlet(name= "MyServlet", urlPatterns = { "/wsexample"})public class MyServlet extendsWebSocketServlet {private static final long serialVersionUID = 1L;

@Overridepublic voiddoGet(HttpServletRequest request,

HttpServletResponse response)throwsServletException, IOException {

response.getWriter().println("HTTP GET method not implemented.");

}

@Overridepublic voidconfigure(WebSocketServletFactory factory) {

factory.getPolicy().setIdleTimeout(10000);

factory.register(MySocket.class);

}

}

MySocket.java 是socket具体处理类,写法在jetty7和jetty9有很大的不同。

importjava.io.IOException;importorg.eclipse.jetty.websocket.api.Session;importorg.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;importorg.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;importorg.eclipse.jetty.websocket.api.annotations.OnWebSocketError;importorg.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;importorg.eclipse.jetty.websocket.api.annotations.WebSocket;

@WebSocketpublic classMySocket {

Session WebSession;

@OnWebSocketClosepublic void onClose(intstatusCode, String reason) {

System.out.println("Close: " +reason);

}

@OnWebSocketErrorpublic voidonError(Throwable t) {

System.out.println("Error: " +t.getMessage());

}//客户端连接

@OnWebSocketConnectpublic voidonConnect(Session session) {

WebSession=session;

System.out.println("Connect: " +session.getRemoteAddress().getAddress());try{

session.getRemote().sendString("你好!客户端。我是服务端。
");

}catch(IOException e) {

System.out.println("IO Exception");

}

}//接收到客户端的文本消息

@OnWebSocketMessagepublic voidonMessage(String message) {

System.out.println("客户端消息: " +message);try{

WebSession.getRemote().sendString("客户端,我收到这条消息了:" +message);

}catch(IOException e) {

System.out.println("IO Exception");

}

}

}

测试一下吧

c76101ec00737c4813d84ab7f8ba533a.png

客户端运行结果:

611e37ea29e80eca6a2577a73d30ce06.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值