NutzCN Logo
问答 对nutz提供的websocket的疑惑
发布于 2759天前 作者 蛋蛋的忧伤 2457 次浏览 复制 上一个帖子 下一个帖子
标签:

我开始使用的原生websocket,但要求使用nutz提供的ioc,又加上了nutz提供的插件,然后可以正常工作,但是我现在又感觉自己写的不靠谱,想使用nutz提供的websocket插件的所有功能,我就继承了AbstractWsEndpoint抽象类,但我发现我原来我的 @onOpen,@onMessage等注解方法都挂了...走了AbstractWsEndpoint抽象类里的onOpen,onClose等方法.. 然后我就不清楚使用nutzwebsocket插件应该是怎样个开发流程? 求指教

15 回复

在你的onOpen和onClose方法加上相关注解

另外, 如果只是为了ioc, 并不不需要继承AbstractWsEndpoint

首先要加什么注解?然后我在我的方法上加了注解会不会AbstractWsEndpoint类里的onOpen等方法都不走了?我可是需要nutz为我维护用户连接的

加上@OnOpen/@OnClose/@OnMessage, 并且调用super.xxxx不就好了

我加了,但是就是没走,开始没继承AbstractWsEndpoint 这些方法走,但是继承后就不走这些了,走父类里的onOpen...

package com.mychat.socket;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.plugins.mvc.websocket.AbstractWsEndpoint;
import org.nutz.plugins.mvc.websocket.NutWsConfigurator;

import com.mychat.dao.UserDao;
import com.mychat.msg.entity.ReceiveMessage;
import com.mychat.msg.entity.SendMessage;

@IocBean
@ServerEndpoint(value = "/chat", configurator=NutWsConfigurator.class)
public class ChatSocket extends AbstractWsEndpoint{
	
	
	@Inject
	private UserDao userDao;
	
	public static Map<String,Session> onlineUsers = new HashMap<String,Session>();//在线用户列表
	private String username;	//当前会话的用户名
	private int id;	//当前用户id
	
	public ChatSocket(){
		System.out.println("create chatsocket...");
	}
	
	
	/**
	 * 连接打开时的回调
	 * @param session
	 */
	@OnOpen
	public void open(Session session,EndpointConfig config){
		super.onOpen(session, config);
		String strs = session.getQueryString();
		System.out.println(strs);
		String username = strs.split("=")[1];
		username = username.substring(0,username.length()-3);
		int id = Integer.valueOf(strs.split("=")[2]);
		try {
			username = URLDecoder.decode(username,"utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		this.username = username;
		this.id = id;
		System.out.println(username+"上线了...");
		onlineUsers.put(username, session);
		System.out.println("当前在线:"+onlineUsers);
		
	}
	
	/**
	 * 连接关闭时的回调
	 * @param session
	 */
	@OnClose
	public void close(Session session){
		try {
			session.close();
		} catch (IOException e) {
			System.out.println("我捕获到了异常...");
			e.printStackTrace();
		}
		onlineUsers.remove(this.username);
		userDao.hide(id);
		System.out.println(username+"下线了...");
		System.out.println("当前在线:"+onlineUsers);
	}
	
	/**
	 * 接受到消息时的回调
	 * @param session 当前sessino
	 * @param msg 消息内容
	 */
	@OnMessage
	public void message(Session session,String msg){
		//解析消息内容
		ReceiveMessage message =Json.fromJson(ReceiveMessage.class,msg);
		Map<String, String> to = message.getTo();
		Map<String, String> mine = message.getMine();
		String toName = to.get("name");	
		Session toSession = onlineUsers.get(toName);
		//构建转发消息实体
		SendMessage sendMessage = new SendMessage();
		sendMessage.setUsername(mine.get("username"));
		sendMessage.setAvatar(mine.get("avatar"));
		sendMessage.setId(mine.get("id"));
		sendMessage.setType("friend");
		sendMessage.setContent(mine.get("content"));
//		if(to.get("username").equals(username)){
//			sendMessage.setMine(true);
//		}else{
//			sendMessage.setMine(false);
//		}
		sendMessage.setFromid(mine.get("id"));
		sendMessage.setTimestamp(System.currentTimeMillis());
		String strJson =Json.toJson(sendMessage);
//		String strJson = sendMessage.toJson();
		//发送消息,记得转成json
		try {
			toSession.getBasicRemote().sendText(strJson);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

看你的代码,并不需要继承AbstractWsEndpoint嘛, 仅为了拿到Dao实例

http://nutzam.com/core/ioc/ioc_by_hand.html

不不不,我现在的代码是自己维护socket连接,我需要nutz为我维护连接,还有提供的那些房子啊,header啊啥的

就是核心技术点,维护链接,发送消息,接受消息等一些我需要nutz帮我干,因为我怕我写的东西效率,安全,性能上等等会出问题,说白了只想写业务 - -|

那把这些代码删了,自定义一个WsHandler,然后覆盖AbstractWsEndpoint的createHandler就好了

先问一下 WsHandler 代表什么..

一个接口啊... 你看看createHandler方法就懂了

就那几个类几个接口,我都看了好几遍了...一上午都在研究这个....就是不太懂每个类/接口代表什么. 尤其是开始的时候 Handler和Room,因为我才刚做开发,比较菜= =,平时也不怎么看大牛写的源码

非常感谢,我大概了解了. 祝贵公司发大财~

简单来说是这样写

@IocBean
@ServerEndpoint(value = "/chat", configurator=NutWsConfigurator.class)
public class ChatSocket extends AbstractWsEndpoint{
    @Inject Dao dao;
    public WsHandler createHandler(Session session, EndpointConfig config) {
        ChatWsHandler handler = new ChatWsHandler(roomPrefix, dao);
        handler.setRoomProvider(roomProvider);
        handler.setSession(session);
        return handler;
    }
}

public ChatWsHandler extends SimpleWsHandler {
    private Dao dao;
    public ChatWsHandler(String prefix, Dao dao) {
       super(prefix);
        this.dao = dao;
    }

    public void onMessage(String message) {
        try {
            NutMap msg = Json.fromJson(NutMap.class, message);
            String action = msg.getString("action");
            if (Strings.isBlank(action))
                return;
            String room = msg.getString("room");
            switch (action) {
            case "join":
                join(room);
                break;
            case "left":
                left(room);
                break;
            case "send":
                 // 处理发送过来的消息
                break;
            default:
                break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

非常感谢,写的非常通俗易懂, nutz因wendal更加美好!

添加回复
请先登陆
回到顶部