NutzCN Logo
问答 nutzsocket问题,我在自定义headler里如何发消息?
发布于 2796天前 作者 蛋蛋的忧伤 1838 次浏览 复制 上一个帖子 下一个帖子
标签:

问题是: 我在自定义的headler里如何给指定连接socket发消息?
我的思路是在第一次连接时,走onOpen方法时维护在map里, headler里拿到socket连接对象,然后从里面拿出来保持的所有连接,获取对应wsid的连接.
然后我的ioc又挂了....
socket代码:

package com.mychat.socket;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

import javax.websocket.CloseReason;
import javax.websocket.EndpointConfig;
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.plugins.mvc.websocket.AbstractWsEndpoint;
import org.nutz.plugins.mvc.websocket.NutWsConfigurator;
import org.nutz.plugins.mvc.websocket.WsHandler;

import com.mychat.dao.UserDao;

import handler.ChatHandler;

@IocBean(name="nutSocket")
@ServerEndpoint(value = "/chat2", configurator=NutWsConfigurator.class)
public class NutSocket extends AbstractWsEndpoint {
	@Inject
	private UserDao userDao;
	private String username;	//当前会话的用户名
	private int id;	//当前用户id
	
	
	
	/**
	 * 连接打开时的回调
	 * @param session
	 */
	public void onOpen(Session session, EndpointConfig config) {
		changeSessionId(session);
        String wsid = session.getId();
     	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]);	//截取id
		try {
			username = URLDecoder.decode(username,"utf-8");	//转码
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		this.username = username;
		this.id = id;
        WsHandler handler = createHandler(session, config);
        handler.setRoomProvider(roomProvider);
        handler.setSession(session);
        session.addMessageHandler(handler);
        sessions.put(wsid, session);
        handlers.put(username, handler);
        
        System.out.println(username+"上线了...");
		System.out.println("当前在线:"+handlers);
	}
	
	/**
	 * 连接关闭时回调
	 */
	public void onClose(Session session, CloseReason closeReason) {
		System.out.println(username+" execute onClose...");
		super.onClose(session, closeReason);
	}
	
	/**
     * WebSocket会话出错时调用,默认调用onClose.
     */
    public void onError(Session session, java.lang.Throwable throwable) {
    	System.out.println(username+" execute onError...");
        onClose(session, null);
    }
	
	
    public WsHandler createHandler(Session session, EndpointConfig config) {
		System.out.println("覆盖父类heander...");
		ChatHandler handler = new ChatHandler(roomPrefix);
        handler.setRoomProvider(roomProvider);
        handler.setSession(session);
        return handler;
	}
}

自定义headler代码:

package handler;

import java.io.IOException;
import java.util.Map;

import javax.websocket.MessageHandler;
import javax.websocket.Session;

import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.plugins.mvc.websocket.handler.AbstractWsHandler;

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

@IocBean
public class ChatHandler extends AbstractWsHandler implements MessageHandler.Whole<String> {
	@Inject
	private UserDao userDao;         //此处为null
	@Inject(value="nutSocket")
	private NutSocket socket;       //此处也为null
	
	public ChatHandler() {
	    this("wsroom:");
	}
	public ChatHandler(String prefix) {
		super(prefix);
	}
	
	@Override
	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":
                 // 处理发送过来的消息
            	System.out.println("execute method message...");
        		//解析消息内容
        		ReceiveMessage msgData =Json.fromJson(ReceiveMessage.class,message);
        		Map<String, String> to = msgData.getTo();
        		Map<String, String> mine = msgData.getMine();
        		String toName = to.get("name");	
        		
        		//构建转发消息实体
        		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 {
//        			Session toSession = socket.getSession(toName);
//        			toSession.getBasicRemote().sendText(strJson);
        			socket.sendJson(toName, sendMessage);                 //由于依赖注入失败,所以此地抛空指针
        		} catch (Exception e) {
        			e.printStackTrace();
        		}
                break;
            default:
                break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
	}
}

首先我的思路可不可行,然后我这问题出在哪里= =麻烦wendal了

1 回复

@IocBean默认是单例

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