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工具,便于调试。

工程目录结构:

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

 <context-param>
   <param-name>debug</param-name>
   <param-value>false</param-value>
 </context-param>

 <session-config>  <!--  10 minutes -->
   <session-timeout>10</session-timeout>
 </session-config>

<servlet>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>MyServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/wsexample</url-pattern>
</servlet-mapping>

 <welcome-file-list>
   <welcome-file>index.html</welcome-file>
   <welcome-file>index.htm</welcome-file>
   <welcome-file>index.jsp</welcome-file>
   <welcome-file>default.html</welcome-file>
   <welcome-file>default.htm</welcome-file>
   <welcome-file>default.jsp</welcome-file>
 </welcome-file-list>

</web-app>

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

build.xml

jetty.lib.dir、deploy.path请自行修改
<?xml version="1.0" encoding="UTF-8"?>

<project name="WebSocket" default="compile">

    <property name="name" value="ws"/>
    <property environment="env"/>
    <property name="src.dir" value="src"/>
    <property name="web.dir" value="WebContent" />
    <property name="build.dir" location="${web.dir}/WEB-INF/classes"/>
    <property name="jetty.lib.dir" location="D:/Software/jetty93/lib"/>
    <property name="dist.dir" location="dist"/>
    <property name="deploy.path" location="D:/Software/jetty93/webapps"/>

    <path id="compile.classpath">
        <fileset dir="${jetty.lib.dir}"/>
    </path>

    <target name="init">
        <mkdir dir="${build.dir}"/>
        <mkdir dir="${dist.dir}"/>
    </target>     

    <target name="compile" depends="init">
        <javac srcdir="${src.dir}" destdir="${build.dir}"
               includeantruntime="false">
            <classpath refid="compile.classpath"/>
        </javac>
        <echo>Compilation completed</echo>
    </target>

    <target name="archive" depends="compile">
        <war destfile="${dist.dir}/${name}.war" needxmlfile="false">
            <fileset dir="${web.dir}"/>
        </war>
        <echo>Archive created</echo>
    </target> 

    <target name="clean" depends="init">
        <delete dir="${build.dir}"/>
        <delete dir="${dist.dir}"/>
        <echo>Cleaning completed</echo>
    </target>  

    <target name="deploy" depends="archive">
        <copy file="${dist.dir}/${name}.war" overwrite="true"
              todir="${deploy.path}"/>
        <echo>Archive deployed</echo>
    </target>    

</project>

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>你好!websocket</title>
</head>
<body>
hello,WebSocket
<script src="index.js"></script>
</body>
</html>

index.js

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

ws.onopen = function() {
    document.write("WebSocket opened <br>");
    ws.send("Hello Server");
};

ws.onmessage = function(evt) {
    document.write("Message: " + evt.data);
};

ws.onclose = function() {
    document.write("<br>WebSocket closed");
};

ws.onerror = function(err) {
    document.write("Error: " + err);
};

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

WebSocketServlet 类中 configure(WebSocketServletFactory factory) 用来注册socket处理类和设置连接时长,在这个时长内,保持长连接。
官网的定义:http://www.eclipse.org/jetty/documentation/current/jetty-websocket-server-api.html

MyServlet.java

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

 
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.annotation.WebServlet;
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;

@WebServlet(name = "MyServlet", urlPatterns = { "/wsexample" })
public class MyServlet extends WebSocketServlet {

    private static final long serialVersionUID = 1L;

    @Override
    public void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().println("HTTP GET method not implemented.");
    }

    @Override
    public void configure(WebSocketServletFactory factory) {
        factory.getPolicy().setIdleTimeout(10000);
        factory.register(MySocket.class);
    }
}

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

import java.io.IOException;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;

@WebSocket
public class MySocket {

    Session WebSession;
    @OnWebSocketClose
    public void onClose(int statusCode, String reason) {
        System.out.println("Close: " + reason);
    }

    @OnWebSocketError
    public void onError(Throwable t) {
        System.out.println("Error: " + t.getMessage());
    }

    //客户端连接
    @OnWebSocketConnect
    public void onConnect(Session session) {
        WebSession = session;
        System.out.println("Connect: " + session.getRemoteAddress().getAddress());

        try {
            session.getRemote().sendString("你好!客户端。我是服务端。<br>");
        } catch (IOException e) {
            System.out.println("IO Exception");
        }
    }

    //接收到客户端的文本消息
    @OnWebSocketMessage
    public void onMessage(String message) {
        System.out.println("客户端消息: " + message);
        try {
            WebSession.getRemote().sendString("客户端,我收到这条消息了:" + message);
        } catch (IOException e) {
            System.out.println("IO Exception");
        }
    }
}

测试一下吧

客户端运行结果:

完整源代码下载 : source code

时间: 2024-12-21 02:54:30

WebSocket集成XMPP网页即时通讯1:Java Web Project服务端/客户端Jetty9开发初探的相关文章

Android学习笔记--基于XMPP的即时通讯

一.常见即时通讯实现 socket openfire+asmack 环信 信鸽 融云 二.XMPP优势 1. 开放性 XMPP协议是自由.开放.公开的,并且易于了解.而且在客户端.服务器.组件.源码库等方面,都已经各自有多种实现. 2.跨平台 客户端只要基于XMPP协议,不管是什么平台(包括不同的移动终端)都可以互联互通. 三.XMPP协议简介 The Extensible Messaging and Presence Protocol (可扩展通讯和表示协议) XMPP 以 Jabber 协议

XMPP - 实现即时通讯相关库

XMPP : 是即时通讯协议,基于 XML . Openfire :是一个 XMPP 协议的Java实现的IM服务器程序,底层使用 Mina 框架. 基于环信 IM 长连接技术,支持亿级用户同时在线. 基于WEB的即时消息传输平台,原来的JiveMessenger. 开源的实时协作RTC服务器,基于XMPP协议,构建高效率的通信服务器.利用WEB进行管理. Smack :是开源.易于使用的 XMPP(jabber) 客户端类库.java写的xmpp客户端代码库.是 Spark 的核心代码.接收消

Android基于XMPP的即时通讯2-文件传输

本文是在上一篇博文Android基于XMPP的即时通讯1-基本对话的基础上,添加新的功能,文件传输 1.初始化文件传输管理类 public static FileTransferManager getFileTransferManager() { if (fileManager == null) { ServiceDiscoveryManager sdManager = ServiceDiscoveryManager .getInstanceFor(connection); if (sdMana

Android基于XMPP的即时通讯3-表情发送

这篇博文主要讲表情发送的一些东西. 参考:Android基于XMPP的即时通讯1-基本对话 1.准备好资源文件 采用的是emoji的表情,我打包好了,下载地址:http://files.cnblogs.com/files/pear-lemon/drawable.zip 2.表情布局文件layout_send_emotion.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmln

红叶倾城一键网页游戏服务端+客户端(无须安装Java)源码

倾城的一键安装版服务端(包括客户端) , 无须安装Java,直接启动服务端就可进入游戏!!!新开服添加首个GM的方法:注册帐号并登陆游戏创建角色名称后,再服务端控制台中输入gmGrade 玩家角色名称 255即成功升级该角色为GM(注意输入的命令的大小写)//////////////////////////////////////////changeHeroLevel 玩家角色名称 级别/addPlayerTreasure 玩家角色名称 数量                /addGoods 物

solve the problem of &#39;java web project cannot display verification code&#39;

my java code of the function: package com.util; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; import javax.servlet.ServletException;

delphi调用 java 的 WebService服务端.

// InvRegistry.RegisterInvokeOptions(TypeInfo(ModelADServicePortType), ioLiteral); InvRegistry.RegisterInvokeOptions(TypeInfo(ModelADServicePortType), ioDocument); delphi调用 java 的 WebService服务端.,布布扣,bubuko.com

如何使用IntelliJ IDEA 14创建基于Maven3的Java Web Project

结合其他博主的一些文章,本文介绍了使用IntelliJ IDEA 14创建基于Maven3的Java Web Project 的步骤.同时也介绍了可能出现的错误以及解决方案. 环境介绍: 系统:OS X Yosemite (10.10.5) IDE :IntelliJ IDEA 14.1.4 Java :Oracle Java 1.8.0_51 Maven:3.3.3 创建步骤: 创建项目:Create New Project —> 设置SDK, 选择Maven, create from arc

MMORPG网页游戏斩仙录全套源码(服务端+客户端)

斩仙录全套源码(服务端+客户端),<斩仙录>是一款具有浓厚中国风的仙侠MMORPG网页游戏,游戏的背景取材于中国瑰丽多姿的神话故事和民间佳传,玩家可以穿越时空与不同时代的著名人物相遇,共同演绎改编自<山海经>.<白蛇传>.<倩女幽魂>.<画皮>.<精卫填海>.<西游记>.<封神榜>等传世佳作中的精彩桥段. 游戏的美术神话风很强,服务端用c++开发,网页端用flash as+js开发,含fla源文件,解压后702