// -=-=-=-=-=-=-=- MembershipListener Interface -=-=-=-=-=-=-=- public void viewAccepted(GCT.View new_view) { members = new Hashtable(); ArrayList tmpMbrs = new_view.getMembers(); for (int x = 0; x < tmpMbrs.Count; x++) { members.Add((Address)tmpMbrs[x], "User" + x); } updateMembers(); }
/// <summary> /// Called by the ProtocolSinkStack when messages are recevied. /// </summary> /// <param name="evt">Event that has been received.</param> public void up(Event evt) { int type=evt.Type; Message msg; /*if the queue is not available, there is no point in *processing the message at all*/ if(mq == null) { if(Trace.trace) Trace.error("GroupChannel.up()", "message queue is null"); return; } switch(type) { case Event.MSG: msg=(Message)evt.Arg; if(!receive_local_msgs) { // discard local messages (sent by myself to me) if(local_addr != null && msg.Source != null) if(local_addr.Equals(msg.Source)) return; } break; case Event.VIEW_CHANGE: my_view=(View)evt.Arg; if(!receive_views) // discard if client has not set receving views to on return; break; case Event.SUSPECT: if(!receive_suspects) return; break; case Event.CONNECT_OK: lock(connect_mutex) { Monitor.Pulse(connect_mutex); } break; case Event.DISCONNECT_OK: lock(disconnect_mutex) { Monitor.Pulse(disconnect_mutex); } break; case Event.SET_LOCAL_ADDRESS: local_addr=(Address)evt.Arg; break; case Event.EXIT: handleExit(evt); return; // no need to pass event up; already done in handleExit() default: break; } // If UpHandler is installed, pass all events to it and return (UpHandler is e.g. a building block) if(up_handler != null) { up_handler.up(evt); return; } if(type == Event.MSG || type == Event.VIEW_CHANGE || type == Event.SUSPECT || type == Event.EXIT) //type == Event.GET_APPLSTATE || type == Event.BLOCK { try { mq.Add(evt); } catch(Exception e) { if(Trace.trace) Trace.error("GroupChannel.up()", "exception: " + e); } } }
/// <summary> /// Connects the channel the specified group /// </summary> /// <param name="channel_name">Group to connect to.</param> public override void connect(String channel_name) { if (!connected) { /*make sure we have a valid channel name*/ if(channel_name == null) { if(Trace.trace) Trace.error("GroupChannel.connect()", "channel_name is null"); return; } else this.channel_name = channel_name; prot_stack.start(); /* Wait LOCAL_ADDR_TIMEOUT milliseconds for local_addr to have a non-null value (set by SET_LOCAL_ADDRESS) */ lock(local_addr_mutex) { long wait_time=LOCAL_ADDR_TIMEOUT; long start = System.Environment.TickCount; while(local_addr == null && wait_time > 0) { try { Monitor.Wait(local_addr_mutex,(int)wait_time); } catch(ThreadInterruptedException ex) {;} wait_time-=System.Environment.TickCount - start; } } // ProtocolStack.start() must have given us a valid local address; if not we won't be able to continue if(local_addr == null) { if(Trace.trace) Trace.error("GroupChannel.connect()", "local_addr == null; cannot connect"); throw new Exception("local_addr is null"); } ArrayList t=new ArrayList(); t.Add(local_addr); my_view=new View(local_addr, 0, t); // create a dummy view /* Send down a CONNECT event. The CONNECT event travels down to the GMS, where a * CONNECT_OK response is generated and sent up the stack. GroupChannel blocks until a * CONNECT_OK has been received, or until timeout has elapsed. */ //Event connect_event = new Event(Event.CONNECT, channel_name); //down(connect_event); lock(connect_mutex) { try { Event connect_event = new Event(Event.CONNECT, channel_name); down(connect_event); // CONNECT is handled by each layer Monitor.Wait(connect_mutex,connectTimeout,true); // wait for CONNECT_OK event } catch(Exception e) { if(Trace.trace) Trace.error("GroupChannel.connect()", "exception: " + e); } } connected = true; /*notify any channel listeners*/ connected=true; if(channel_listener != null) channel_listener.channelConnected(this); } }
static void Main(string[] args) { Tester.SetupDebug(); NAKACK nak = new NAKACK(); Protocol bottom = null; Protocol top = Tester.createStack(nak, out bottom); Address remote1 = new Address("1.1.1.1",8005); Address remote2 = new Address("1.1.1.2",8005); Address remote3 = new Address("1.1.1.3",8005); ArrayList members = new ArrayList(); members.Add(Tester.localAddr); members.Add(remote1); members.Add(remote2); members.Add(remote3); View newView = new View(new ViewId(Tester.localAddr,0),members); evt = new Event(Event.VIEW_CHANGE,newView); top.down(evt); evt = new Event(Event.MSG,new Message(null,null,"Message 1")); top.down(evt); evt = new Event(Event.MSG,new Message(null,null,"Message 2")); top.down(evt); evt = new Event(Event.MSG,new Message(null,null,"Message 3")); top.down(evt); Console.WriteLine("-=-=-=-=- Received Msg 0 from Remote 1 -=-=-=-=-=-"); Message msg = new Message(null,remote1,"Incoming Message 0"); msg.Headers.Add("NAKACK",new NakAckHeader(NakAckHeader.MSG, 0)); evt = new Event(Event.MSG,msg); bottom.up(evt); Console.WriteLine("-=-=-=-=- Received Msg 0 from Remote 2 -=-=-=-=-=-"); msg = new Message(null,remote2,"Incoming Message 0"); msg.Headers.Add("NAKACK",new NakAckHeader(NakAckHeader.MSG, 0)); evt = new Event(Event.MSG,msg); bottom.up(evt); Console.WriteLine("-=-=-=-=- Received Msg 1 from Remote 1 -=-=-=-=-=-"); msg = new Message(null,remote1,"Incoming Message 1"); msg.Headers.Add("NAKACK",new NakAckHeader(NakAckHeader.MSG, 1)); evt = new Event(Event.MSG,msg); bottom.up(evt); Console.WriteLine("-=-=-=-=- Received Msg 2 from Remote 2 -=-=-=-=-=-"); msg = new Message(null,remote2,"Incoming Message 2"); msg.Headers.Add("NAKACK",new NakAckHeader(NakAckHeader.MSG, 2)); evt = new Event(Event.MSG,msg); bottom.up(evt); Thread.Sleep(20000); Console.WriteLine("-=-=-=-=- Received Msg 1 from Remote 2 -=-=-=-=-=-"); msg = new Message(null,remote2,"Incoming Message 1"); msg.Headers.Add("NAKACK",new NakAckHeader(NakAckHeader.MSG, 1)); evt = new Event(Event.MSG,msg); bottom.up(evt); Thread.Sleep(3000); Console.WriteLine("-=-=-=-=- Receiving STABLE event -=-=-=-=-=-"); Digest digest = new Digest(4); // 4 members digest.add(Tester.localAddr, 0, 2, 2); digest.add(remote1, 0, 1, 1); digest.add(remote2, 0, 2, 2); digest.add(remote3, 0, 0, 0); evt = new Event(Event.STABLE,digest); bottom.up(evt); Console.ReadLine(); Tester.stopProtocols(top); Console.ReadLine(); }