websocket点对点聊天java实例

项目中有个实时聊天的需求,查看很多资料,主要是实现从服务端发送信息到客户端,实现方法有长轮询,长连接,websocket等,还是websocket最简单,不过需要浏览器支持。

需要的支持

需要jdk7以上,tomcat7以上,反正我的7.0.55是不行,7.0.64可以,,引入

javax.websocket
api地址

socket.java

import bo.MessageChat;
import bo.SessionMap;
import com.alibaba.fastjson.JSONArray;
import server.ChatInfoServer;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

/**
 * Created by keygod on 2016/4/25.
 */
@ServerEndpoint(value ="/websocket/{from}/{to}")
public class SocketChat{

    private ChatInfoServer chatInfoServer = new ChatInfoServer();

    private String from;
    private String to;
    private Session session;
    private static final Logger sysLogger = Logger.getLogger("sysLog");

    @OnOpen
    public void open(Session session,  @PathParam(value = "from")String from,@PathParam(value = "to")String to) throws IOException {
        this.session = session;
        this.from = from;
        this.to = to;
        SessionMap.getSessionMap().put(from,session);
        List<MessageChat> messageChats = chatInfoServer.getByFromAndto(from,to,1,5);
        String json = JSONArray.toJSONString(messageChats);
        session.getBasicRemote().sendText(json);

        Session sessionto = SessionMap.getSessionMap().get(to);

        if(sessionto!=null){
            session.getBasicRemote().sendText("online");//接受人的状态  上线
        }else {
            session.getBasicRemote().sendText("offline");//接受人的状态   上线
        }
        sysLogger.info("*** WebSocket opened from ship " + from);
    }

    @OnMessage
    public void inMessage(String message,Session session) {
        try {
            MessageChat messageChat = new MessageChat();
            String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            messageChat.setFromDate(date);
            messageChat.setFromName(from);
            messageChat.setTodate(date);
            messageChat.setToName(to);
            messageChat.setMessage(message);


            Session sessionto = SessionMap.getSessionMap().get(to);
            if(sessionto!=null){
                messageChat.setReadtype("1");
                sysLogger.info("*** *** WebSocket opened to ship " + to);
                sessionto.getBasicRemote().sendText(JSONArray.toJSONString(messageChat));
                session.getBasicRemote().sendText("online");
            }else {
                messageChat.setReadtype("0");
                session.getBasicRemote().sendText("offline");
            }

            chatInfoServer.insert(messageChat);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @OnClose
    public void end() {
        SessionMap.getSessionMap().remove(from);
        sysLogger.info("*** WebSocket closed from sessionId " + this.session.getId());
    }

    @OnError
    public void error(Throwable t) {
        // 添加处理错误的操作
        System.out.println(t.getMessage());
        System.out.println(t.getCause());
        t.printStackTrace();
    }


}

其中 ,SessionMap 用来保存session的key ,因为websocket的session是按照顺序1,2来的,所以每次open链接把session存入全局变量sessionMap中,就可以指定发送人。

发送信息方式为session.getBasicRemote().sendText(“”);

SeesionMap.java

package bo;

import javax.websocket.Session;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Created by keygod on 2016/4/25.
 */
public class SessionMap {

    private static Map<String,Session> sessionMap = new ConcurrentHashMap<String, Session>();

    public static Map<String, Session> getSessionMap() {
        return sessionMap;
    }

    public static void setSessionMap(Map<String, Session> sessionMap) {
        SessionMap.sessionMap = sessionMap;
    }
}

sessionMap需要加锁,

点对点发送信息只需要这两个类,之后就是加上存数据库的操作了。。

404问题

首先依赖环境是
WebSocket是HTML5才支持的
Java EE 7.0以后的版本才支持
Tomcat7以后的版本才支持
其他的服务容器则应该是有对应的自己支持的包

具体的如何请求和接受就不做记录了,主要似乎404的问题

而Oracle 自己的WebSocket包在目前为止最新的是 WebSocket-api1.0 release版本
Maven配置如下
http://mvnrepository.com/artifact/javax.websocket/javax.websocket-api/1.0
Xml代码 收藏代码

javax.websocket
javax.websocket-api
1.0

注意一点是(404的原因)就要引入Tomcat7的 Run Time 的依赖包,不要用WebSocket-api.jar
Tomcat7内部有Tomat7-WebSocket.jar 和 WebSocket-api.jar的包,里面实现了这个基于WebSocket-api.jar的内容,基于这个包的基础上又进行修饰的包
在 Tomcat运行时环境 卡特琳娜里面的,所以,要是用Maven部署的话,会有Jar包冲突

而在开发的过程中,就要引入Tomcat7的 Run Time 的依赖包,不要用WebSocket-api.jar

这是Tomcat7的关于WebSocket的说明文档,未来使用WebSocket-api.jar,Tomcat说将在Tomcat 8的版本移出自己内部的包,就可以直接使用Oracle的了
http://tomcat.apache.org/tomcat-7.0-doc/web-socket-howto.html

其他404,那可能就是代码里面访问的路径错误导致找不到啦

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值