view rep/handler/FirstConnector.java @ 450:21cb16b7f3df

block message in Editor.write()
author one
date Thu, 23 Sep 2010 18:15:37 +0900
parents 18cacd0b3ccf
children
line wrap: on
line source

package rep.handler;

import java.io.IOException;

import rep.PacketSet;
import rep.REP;
import rep.REPCommand;
import rep.ServerMainLoop;
import rep.Session;
import rep.SessionManager;
import rep.channel.REPSelectionKey;
import rep.channel.REPSocketChannel;

public class FirstConnector extends Forwarder {

	/**
	 * Handle first incoming packet, and determines master editor or 
	 * client editor ( or possibly inter-connected session manager).
	 * We cannot send anything but sm_join().
	 * 
	 * @param manager
	 * @param channel
	 */
	public FirstConnector(SessionManager manager,
			REPSocketChannel<REPCommand> channel) {
		super(manager,channel);
	}

	public void cancel(REPSocketChannel<REPCommand> socketChannel) {
		manager.remove(socketChannel);
	}

	@Override
	public void handle(REPCommand command, REPSelectionKey<REPCommand> key) throws IOException {
		/*
		 * 接続要求は、EditorかSlave Editorで、
		 *    join, put, sm_join
		 * が来る。それ以外はエラー。master もありか?
		 *      sm_join_ack
		 */
		REPNode fw;
		ServerMainLoop.logger.writeLog("FirstConnector: command = " + command);
		switch(command.cmd) {
		case SMCMD_JOIN: 
		{
			//どのSessionにも属さないエディタをリストに追加
			//エディタとchannelは1対1 (ではないかも)
			//エディタが新しくputする場合は新しくソケットを作る
			//   1対1でない場合は、multiplexerを挿めば良い
			REPNode editor = manager.newEditor(channel);
			editor.setHost(manager.myHost());
			command.eid = editor.eid;
			command.sid = -1;
			editor.setSID(-1);
			fw = editor;
			break;
		}
		case SMCMD_PUT:
		{
			//  新しいeditorとsessionをここで作る。eid,sidは、
			//  session manager IDが付いているので、global unique
			REPNode editor = manager.newEditor(channel);
			Session session = manager.newSession(editor);
			session.setName(command.string);
			editor.setName(command.string);
			editor.setSID(session.getSID());
			command.eid = editor.eid;
			command.sid = editor.sid;
			fw = editor;
			break;
		}
		case SMCMD_SM_JOIN:
		{
			fw = new Dispatcher(manager,channel); // FirstConnector?
			manager.addWaitingSessionManager(fw, command);
			break;
		}
		case SMCMD_SM_JOIN_ACK:
			manager.setSessionManagerID(command.sid);
			manager.afterConnect();
			fw = new Dispatcher(manager,channel);
			manager.setParent(fw);
			break;
		default: throw new IOException();
		}
		//myHost を設定。
		//立ち上げ時にやるとlocalhostしか取れない
		if(manager.myHost() == null) manager.setMyHostName(getLocalHostName());
		fw.setMode(command.cmd);
		fw.setHost(manager.myHost());
		manager.registerChannel(channel, fw);
		manager.sessionManage(fw, command);
	
	}

	@Override
	public void send(REPCommand command) {
		assert(command!=null && command.cmd==REP.SMCMD_SM_JOIN);
		assert(channel!=null);
		REPCommand c = new REPCommand(command);
		manager.addWriteQueue(new PacketSet(this,  c));
	}
}