> Ah, I forgot the original context you were working in!
>   
I did too :) I didn't communicate it clearly, I think. I was trying to 
accomplish too much too quickly.
This is exactly what I hoped for, a solution that would not force me to 
disconnect and reconnect.
Let me give this a go and get back to you tonight  EST, which is your 
morning tomorrow.
Thanks again!
Gloria
> All the suggestions I've made previously could be considered as trying to  
> this problem: that the ConsoleReader component not only reads user input,  
> but also generates a prompt for it (which it directly writes to the  
> console (standard output).
>
> It sounds like what you actually are after building is a simple chat  
> protocol - abstracted away from having to know about where its input is  
> coming from or where its output is going to. The ConsoleReader component  
> mixes a bit of both - it handles the sourcing of input, but also generates  
> some output itself (the prompt) and worse still, it puts this output onto  
> the console directly! :-)
>
> So what you're actually after is what you originally had:
>
>      Pipeline(
>          SourceOfInput(),
>          MyComponent(),
>          DestinationForOutput()
>      )
>
> So for testing your chat protocol component MyComponent - we can still use  
> ConsoleReader and ConsoleEchoer. We just have to ignore the '>>>' prompt  
> generated by the ConsoleReader and pretend its not there.
>
> When you plug Mycomponent into the ConnectedServer (also known as  
> SimpleServer in more recent subversion copies of Kamaelia iirc) as its  
> protocol, it gets wired up in much the same way as above - data coming  
>  from the client will get send to its inbox and data send out of its outbox  
> will be sent back to the client.
>
> So all of the Seq stuff is not strictly necessary. All you need to do is  
> encode the sequential behaviour into the main() generator in MyComponent.  
> For example something along the lines of this (note the shutdown handling  
> makes it a little messier that it might otherwise be):
>
>      def main(self):
>          mustStop = false;
>
>          # 1) generate login prompt
>          self.send("Enter username:", "outbox")
>
>          # 2) wait for response
>          mustStop = self.doShutdown()
>          while not mustStop and not self.dataReady("inbox"):
>              self.pause()
>              yield 1
>              mustStop = self.doShutdown()
>
>          if mustStop:
>              return
>
>          username = self.recv("inbox")
>
>          # 3) welcome
>          self.send("Welcome "+username+"! Begin chatting!")
>
>          # 4) do chatting
>          ...
>
> One other thing to consider is that the ConsoleReader specifically buffers  
> input until a whole line is received from the user, before outputting that  
> as a single string message to its "outbox" outbox. Whereas the socket  
> connection may send fragments of strings before a whole line has been  
> entered. A component such as this one can sort that out for you:  
> http://www.kamaelia.org/Components/pydoc/Kamaelia.Visualisation.PhysicsGraph.chunks_to_lines.html
>
> Simply pipeline it with MyComponent and make that the protocol thats given  
> to the ConnectedServer:
>
>      def myProtocol():
>          return Pipeline(
>              chunks_to_lines(),
>              MyComponent()
>          )
>
>      ...
>
>      ConnectedServer(protocol=myProtocol, port=WHATEVER).run()
>
>
>
> Matt
>
>
> On Tue, 03 Mar 2009 04:35:07 -0000, Gloria W <[email protected]> wrote:
>
>   
>> I got the carousel example working, but it sends/receives from/to the
>> original console, not any new client which connects. I realized I can
>> reuse the ConsoleEchoer, but somehow make it send a string to a client
>> upon connect, and have the server process the string instead of echoing
>> it to the server's console.
>> I tried this, but all proposed solutions so far write to the console,
>> not a newly connected client. Maybe I am missing something, btu I think
>> I am close.
>>
>>  Aside from this, I was wondering if a carousel or seq will be
>> appropriate to solve my problem.
>>
>> I am trying to simulate what happens in crude chat systems such as IRC.
>> For simplicity, in this example the user connects, is prompted for a
>> name, and then can chat freely.
>> If I have two pipelines: one detects client connect and is prompting for
>> a name, receiving the response, and then handing control over to another
>> pipeline; doesn't this require a disconnect/reconnect with the client?
>> If so, this would be bad, because the user would have to re-telnet in,
>> would not be "logged in", and would have to start again.
>>
>> So I guess if I get the data flow working, I can write this logic in one
>> pipeline, and reuse the same connection, assuming the first thing a user
>> types after connecting would be the name. Or maybe there is a clever way
>> to hand off a connected pipline to another utility, so that my flow
>> control is cleaner? (not running an "if name is set" check upon each
>> message).
>>
>> Thanks again for your help,
>> Gloria
>>
>>
>>     
>>>  This is really cool, and exactly what I need. I will get some time
>>> later to implement this and try it out, and I am sure I'll have more
>>> questions and comments.
>>> Thanks again for this.
>>> Gloria
>>>       
>>>> On Mar 2, 8:36 pm, Gloria W <[email protected]> wrote:
>>>>
>>>>         
>>>>> Matt, thanks for this response. It took me a while to get through it  
>>>>> and
>>>>> make sure I understood each point. I appreciate it, comments are  
>>>>> below.
>>>>>
>>>>>           
>>>> No problem.
>>>>
>>>> I've just realised another way to achieve the same effect that is
>>>> probably simpler!
>>>>
>>>> There *is* a component that is all about getting things done in an
>>>> order: the Seq component (The name is a homage to the OCCAM language):
>>>>
>>>>     http://www.kamaelia.org/Components/pydoc/Kamaelia.Chassis.Seq.html
>>>>
>>>> With Seq, you provide a list of components. Seq goes through the list,
>>>> starting with the first component. It activates it and wires up its
>>>> inboxes and outboxes so that they're mapped to the Seq component's
>>>> inboxes and outboxes (just like the Carousel does). When that
>>>> component finishes, it then unwires it and moves onto the next in the
>>>> list. It therefore effectively runs them *in sequence* one after the
>>>> other.
>>>>
>>>> We've got two steps: displaying the initial message, then taking user
>>>> input. Both steps need their output to be displayed. So we'll create a
>>>> Seq componet, Pipeline'd into a console echoer:
>>>>
>>>>     from Kamaelia.Chassis.Seq import Seq
>>>>
>>>>     Pipeline(
>>>>         Seq( ... args to be determined! ... ),
>>>>         ConsoleEchoer()
>>>>     ).run()
>>>>
>>>> We can use a OneShot component (see  
>>>> http://www.kamaelia.org/Components/pydoc/Kamaelia.Util.OneShot.html
>>>> ) to send that initial message, so that it gets sent to the
>>>> ConsoleEchoer and displayed. OneShot, rather conveniently, then
>>>> immediately terminates; so the Seq component will move onto the next
>>>> component in its list. That next component can be the Pipeline of a
>>>> ConsoleReader, sending its output into MyComponent.
>>>>
>>>> So what we have is:
>>>>
>>>>     from Kamaelia.Chassis.Seq import Seq
>>>>     from Kamaelia.Util.OneShot import OneShot
>>>>
>>>>     Pipeline(
>>>>         Seq(
>>>>             OneShot("initial message to be displayed"),
>>>>             Pipeline(
>>>>                 ConsoleReader(),
>>>>                 MyComponent()
>>>>             )
>>>>         ),
>>>>         ConsoleEchoer()
>>>>     ).run()
>>>>
>>>> In this case, MyComponent doesn't need to bother to send the initial
>>>> message itself, as it did in the suggestion I previously made.
>>>>
>>>> So what happens here? Well, when the system starts running, initially
>>>> the Seq component selects the first item in its list - the OneShot
>>>> component. So, what actually ends up getting wired up is something
>>>> like this:
>>>>
>>>>     Pipeline(
>>>>         OneShot("initial message to be displayed"),
>>>>         ConsoleEchoer()
>>>>     )
>>>>
>>>> Its not actually exactly like that, because the OneShot is still
>>>> contained within the Seq component - but because all the inboxes and
>>>> outboxes are mapped to that of the Seq component, it is roughly
>>>> equivalent.
>>>>
>>>> Then when the OneShot component has sent its message and terminated,
>>>> the Seq component swaps it out and replaces it with the next thing in
>>>> its list - the pipeline of a ConsoleReader and MyComponent. So the way
>>>> the system is wired up suddenly switches to something akin to this:
>>>>
>>>>     Pipeline(
>>>>         Pipeline(
>>>>             ConsoleReader(),
>>>>             MyComponent()
>>>>         ),
>>>>         ConsoleEchoer()
>>>>     )
>>>>
>>>> Again, the inner pipeline is, in reality, contained within the Seq
>>>> component, but it behaves roughly like it is shown.
>>>>
>>>>
>>>>
>>>>
>>>> Matt
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>         
>>>       
>>     
>
>
>
>   


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"kamaelia" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/kamaelia?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to