Java使用WebSocket(注解实现)

 

我这里的实现方法用的是javax.websocket包下提供的API,也就是j2EE原生的方法。

Java代码如下:

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.apache.log4j.Logger;

/**
 * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
 * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
 * @author 
 */
@ServerEndpoint(value="/websocket")
public class WebSocketTest {
    private static Logger logger = Logger.getLogger(WebSocketTest.class);
   

    //用来存放每个客户端对应的WebSocketTest对象,适用于同时与多个客户端通信
    public static CopyOnWriteArraySet<WebSocketTest> webSocketSet = new CopyOnWriteArraySet<WebSocketTest>();
    //若要实现服务端与指定客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
    public static ConcurrentHashMap<Session,Object> webSocketMap = new ConcurrentHashMap<Session,Object>();

    //与某个客户端的连接会话,通过它实现定向推送(只推送给某个用户)
    private Session session;
	
	

    /**
     * 连接建立成功调用的方法
     *
     * @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    @OnOpen
    public void onOpen(Session session){
        this.session = session;
        webSocketSet.add(this);     //加入set中
        webSocketMap.put(session,this); //加入map中
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session closeSession) {
        webSocketSet.remove(this); //从set中删除
        webSocketMap.remove(closeSession); //从map中删除
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     * @param session 可选的参数
     * @throws Exception 
     */
    @OnMessage
    public void onMessage(String message,Session mySession) throws Exception {
    	
    	logger.info("来自客户端的消息:" + message);
        //--------------群发消息(多用于聊天室场景)
       /* for (WebSocketTest item : webSocketSet) {
            try {
                item.sendAllMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
                continue;
            }
        }*/
    	
    			//推送给单个客户端
			for (Session session : webSocketMap.keySet()) {
				if (session.equals(mySession)) {
					WebSocketTest item = (WebSocketTest) webSocketMap.get(mySession);
					try {
						String msg="嗨,这是返回的信息";
						item.sendMessage(mySession,msg);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}

			
		}
    	 
    	 
    }
   

    /**
     * 发生错误时调用
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        logger.info("发生错误");
       // error.printStackTrace();
    }


    //给所有客户端发送信息
    public void sendAllMessage(String message) throws IOException {
    			this.session.getBasicRemote().sendText(message);
    }

    //定向发送信息
    public void sendMessage(Session mySession,String message) throws IOException {
    	synchronized(this) {try {
			if(mySession.isOpen()){//该session如果已被删除,则不执行发送请求,防止报错
				//this.session.getBasicRemote().sendText(message);
				mySession.getBasicRemote().sendText(message);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

    	}
        

    }





}

   值得注意的一点是,如果想要在如上的websocket中直接注入service或者dao来进行数据库操作是无法注入的。我的解决办法是新建一个专门操作数据库的类并在applicationContext.xml中进行配置。比如我的这个类叫GetDataServiceImpl,首先要在 applicationContext.xml 中加入

<bean id="getDataServiceImpl" class="com.cn.service.impl.GetDataServiceImpl"></bean>

在websocket中通过beanid获取该类

private GetDataServiceImpl getDataServiceImpl = (GetDataServiceImpl) ContextLoader.getCurrentWebApplicationContext().getBean("getDataServiceImpl");

         以上就是我参考网上相关资料后根据自己的理解在SSM框架的基础上整合的websocket代码,并且在项目中已经在使用,目前为止还没有发现什么问题。可以看到,代码其实并不多,而且使用注解方式也比较简单,容易理解。如有不妥之处,欢迎交流指正。

 

 

 

 

  • 4
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 17
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值