> 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
-~----------~----~----~----~------~----~------~--~---