java websocket 实现

本文介绍了如何在Java环境下,利用JDK1.8和Tomcat 8搭建WebSocket通信。通过IntelliJ IDEA作为开发工具,详细阐述了实现WebSocket的具体步骤和技术要点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

环境:jdk1.8 + Tomcat 8

IDE:IntelliJ IDEA 2016.2.4




WebSocket.java
package websocket;

import org.java_websocket.WebSocketImpl;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;

import java.net.InetSocketAddress;
import java.net.UnknownHostException;

/**
 * Created by Administrator on 2016/9/13.
 */
public class WebSocket extends WebSocketServer {

    int j=0;
    int h=0;
    int e=0;
    int l=0;

    public WebSocket(InetSocketAddress address) {
        super(address);
        System.out.println("地址" + address);
    }

    public WebSocket(int port) throws UnknownHostException {
        super(new InetSocketAddress(port));
        System.out.println("端口" + port);
    }

    /**
     * 触发连接事件
     * @param conn
     * @param handshake
     */
    @Override
    public void onOpen(org.java_websocket.WebSocket conn, ClientHandshake handshake) {
        System.out.println("有人连接Socket conn:" + conn);
        l++;
    }

    /**
     * 触发关闭事件
     * @param conn
     * @param message
     * @param reason
     * @param remote
     */
    @Override
    public void onClose(org.java_websocket.WebSocket conn, int message, String reason, boolean remote) {
        userLeave(conn);
    }

    /**
     * 客户端发送消息到服务器是触发事件
     * @param conn
     * @param message
     */
    @Override
    public void onMessage(org.java_websocket.WebSocket conn, String message) {
        if(message != null) {
            //将用户加入
            this.userJoin(message, conn);
        }
    }

    /**
     * 触发异常事件
     * @param conn
     * @param message
     */
    @Override
    public void onError(org.java_websocket.WebSocket conn, Exception message) {
        System.out.println("Socket异常:" + message.toString());
        e++;
    }

    /**
     * 用户下线处理
     * @param conn
     */
    public void userLeave(org.java_websocket.WebSocket conn) {
        String user = WebSocketPool.getUserByKey(conn);
        boolean b = WebSocketPool.removeUser(conn); // 在连接池中移除连接
        if (b) {
            WebSocketPool.sendMessage(user); // 把当前用户从所有在线用户列表中删除
            String leaveMsg = "[系统]" + user + "下线了";
            WebSocketPool.sendMessage(leaveMsg); // 向在线用户发送当前用户退出的信息
        }
    }

    public void userJoin(String user, org.java_websocket.WebSocket conn) {
        WebSocketPool.sendMessage(user); // 把当前用户加入到所有在线用户列表中
        String joinMsg = "[系统]" + user + "上线了!";
        WebSocketPool.sendMessage(joinMsg); // 向所有在线用户推送当前用户上线的消息
        WebSocketPool.addUser(user, conn); // 向连接池添加当前的连接的对象
        WebSocketPool.sendMessageToUser(conn, WebSocketPool.getOnlineUser().toString());
        // 向当前连接发送当前在线用户的列表
    }

    public static void main(String[] args) throws InterruptedException{
//        System.out.println("开始启动webSocket");
//        WebSocketImpl.DEBUG = false;
//        int port = 8888; // 端口随便设置,只要不跟现有端口重复就可以了
//        WebSocket s =null;
//        try {
//            s = new WebSocket(port);
//            s.start();
//        } catch (UnknownHostException e1) {
//            System.out.println("启动webSocket失败!");
//            e1.printStackTrace();
//        }
//        System.out.println("启动webSocket成功!");
    }
}
socket主要函数
main方法是后面测试用的,等会会提到。


WebSocketPool.java
package websocket;

import java.util.*;
import org.java_websocket.WebSocket;

/**
 * Created by Administrator on 2016/9/13.
 */
public class WebSocketPool {
    private static final Map<WebSocket, String> userconnections = new HashMap<WebSocket, String>();

    /**
     * 获取用户名
     * @param conn
     * @return
     */
    public static String getUserByKey(WebSocket conn) {
        return userconnections.get(conn);
    }

    /**
     * 获取在线总数
     * @return
     */
    public static int getUserCount() {
        return userconnections.size();
    }

    /**
     * 获取WebSocket
     * @param user
     * @return
     */
    public static WebSocket getWebSocketByUser(String user) {
        Set<WebSocket> keySet = userconnections.keySet();
        synchronized (keySet) {
            for (WebSocket conn : keySet) {
                String cuser = userconnections.get(conn);
                if (cuser.equals(user)) {
                    return conn;
                }
            }
        }
        return null;
    }

    /**
     * 向连接池中添加连接
     * @param user
     * @param conn
     */
    public static void addUser(String user, WebSocket conn) {
        userconnections.put(conn, user); // 添加连接
    }

    /**
     * 获取所有的在线用户
     * @return
     */
    public static Collection<String> getOnlineUser() {
        List<String> setUsers = new ArrayList<String>();
        Collection<String> setUser = userconnections.values();
        for (String u: setUser) {
            setUsers.add(u);
        }
        return setUsers;
    }

    /**
     * 移除连接池中的连接
     * @param conn
     * @return
     */
    public static boolean removeUser(WebSocket conn) {
        if (userconnections.containsKey(conn)) {
            userconnections.remove(conn); // 移除连接
            return true;
        } else
            return false;
    }

    /**
     * 向特定的用户发送数据
     * @param conn
     * @param message
     */
    public static void sendMessageToUser(WebSocket conn, String message) {
        if (null != conn) {
            conn.send(message);
        }
    }


    public static void sendMessage(String message) {
        Set<WebSocket> keySet = userconnections.keySet();
        synchronized (keySet) {
            for (WebSocket conn : keySet) {
                String user = userconnections.get(conn);
                if (user != null) { conn.send(message);
                }
            }
        }
    }

}
连接池相关函数


http://www.blue-zero.com/websocket/
作者: 手插口袋_
链接:http://www.imooc.com/article/12401
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作!
跑main方法,看看是否能正常启动(看控制台很清楚的),然后打开http://www.blue-zero.com/websocket/
如下图所示
在线测试
http://www.blue-zero.com/websocket/
作者: 手插口袋_
链接:http://www.imooc.com/article/12401
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作!

(我以后也要写一个类似的!!!!)


Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <display-name></display-name>
    <filter>
        <filter-name>startFilter</filter-name>
        <filter-class>filter.startFilter</filter-class>
    </filter>
    <servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>servlet.TestServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/TestServlet</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>
好像少了什么东西,但是不影响结果



startFilter .java
package filter;

import java.io.IOException;
import java.net.UnknownHostException;
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;

import org.java_websocket.WebSocketImpl;

import websocket.WebSocket;

/**
 * Created by Administrator on 2016/9/13.
 */
public class startFilter implements Filter {

    public void destroy() {
    }

    public void doFilter(javax.servlet.ServletRequest req, javax.servlet.ServletResponse resp, javax.servlet.FilterChain chain) throws javax.servlet.ServletException, IOException {
        chain.doFilter(req, resp);
    }

    /**
     * 初始化
     * @param fc
     * @throws ServletException
     */
    public void init(FilterConfig fc) throws ServletException {
        this.starWebSocketOnline();
    }

    /**
     * 启动socket服务
     */
    public void starWebSocketOnline() {
        System.out.println("开始启动webSocket");
        WebSocketImpl.DEBUG = false;
        int port = 8888;
        WebSocket s = null;
        try {
            s = new WebSocket(port);
            s.start();
        } catch (UnknownHostException e) {
            System.out.println("启动webSocket失败!");
            e.printStackTrace();
        }
        System.out.println("启动webSocket成功!");
    }

}
过滤器启动socket服务,这里实质跟main方法差不多




TestServlet .java
package servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by Administrator on 2016/9/14.
 */
public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        super.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // super.doPost(req, resp);
        System.out.println("content" + req.getParameter("content"));
        req.getSession().setAttribute("content", req.getParameter("content"));
        req.getRequestDispatcher("index.jsp").forward(req, resp);
    }
}
一个很简单的servlet


index .jsp
<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2016/9/13
  Time: 10:35
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.*" %>
<%
    String path = request.getContextPath();
    String basepath = request.getScheme() + "://" + request.getServerName() + ":" +
            request.getServerPort() + path + "/";
%>
<html>
<head>
    <base href="<%=basepath%>">

    <title>sunnylinner的WebSocket</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">

    <script src="js/websocket.js"></script>
</head>
<body>
<input type="hidden" value="${content}" id="content">
<form action="TestServlet" method="post">
    content: <input type="text" name="content">
    <button type="submit">登陆</button>
</form>
<span id="span">

</span>
<span id="span1">

</span>
</body>
</html>



websocket .js
/**
 * Created by Administrator on 2016/9/14.
 */
var ws = new WebSocket("ws://127.0.0.1:8888");
ws.onopen = function () { // 当websocket创建成功,即会触发onopen事件
    var content = document.getElementById("content").value;
    if (content == null && content == ""){
        ws.send("sunnylinner"); // 用于将消息发送到服务端
        document.getElementById("span1").innerHTML="1@@1";
    } else {
        ws.send(content);
        document.getElementById("span1").innerHTML="2@@2";
    }
};
ws.onmessage = function (evt) {
    // 当客户端收到服务端发送来的消息时,会触发onmessage事件,参数evt.data中包含server传输过来的数据
    document.getElementById("span1").innerHTML="3@@3";
    document.getElementById("span").innerHTML="当前在线人数为:" + evt.data;
};
ws.onclose = function () {
    // 当客户端收到服务端发送的关闭连接的请求时,触发onclose事件
    alert("WebSocketClosed!");
};
ws.onerror = function () {
    // 如果出现连接,处理,接收,发送数据失败的时候就会触发onerror事件
    alert("WebSocketError!");
}


应该没剩下了,可以直接跑了。至于最后的显示效果, 我就不放出来了,自己去玩吧,有些方法都写好了,可以去实现跟过可能高级一点的功能。
有什么问题在下面提出来吧

资料参考:慕课网







评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值