Need tutorial on Channels, Fibers, and Events/Messages

void.pointer
edited July 2010 in Photon Server
Just to learn the lower-level parts of Photon, I'm implementing a simple MMO without using the MMO components of Photon. I'm currently working directly with a channel and trying to learn how to send events.

Is there a tutorial somewhere that shows how to do this? Looking at the MMO example isn't helping me because it's far too large of a project, and in addition it is using Photon's MMO concepts.

Comments

  • this is actually retlang, see http://code.google.com/p/retlang/
  • Sorry but this doesn't help me at all. I see nothing in the retlang wiki that even remotely looks like things I'm using in Photon (i.e. MessageChannel & Peer.PublishEvent()). I was actually hoping for something a little more specific to Photon. Documentation for the "general case" wouldn't be very helpful to me.

    Perhaps the thing confusing me the most right now is the existence of both MessageChannel.Publish() and MessageChannel.Subscribe()'s second parameter.

    They both seem to be doing the same thing. Basically, if I plan to send an event to all subscribers in a MessageChannel, I would so so using MessageChannel.Publish(). However, I don't see where the callback specified in the 2nd parameter to MessageChannel.Subscribe() comes in. it looks like it's publishing events as well, but I don't know when it would be triggered. Additionally, it seems to be duplicating serialization logic as well.
  • subscribe determines where the messages from publish arrive.
    You are right, that duplicates the serialization logic. This is necessary since each peer might use a different protocol (unity=binary vs flash=amf3). If you know that everyone uses the same protocol you can serialize the events prior to calling publish.
  • Another question:

    What is the point of using a MessageChannel when I can simply iterate my own list of players and call PhotonPeer.SendEvent() directly?
  • In general you ask why should you use the observer pattern. But in this case there's more to it: The channel subscribers are fibers. Every fiber executes actions in a serial order so you don't have to worry about concurrency issues.
  • Boris wrote:
    In general you ask why should you use the observer pattern. But in this case there's more to it: The channel subscribers are fibers. Every fiber executes actions in a serial order so you don't have to worry about concurrency issues.
    That's not what I'm asking in general, because obviously I am a huge advocate of the observer pattern. My intent was to get a little more information on the design surrounding the MessageChannel concept (It's not just the observer pattern; it has a more specific domain that it addresses).

    Could you elaborate a little bit on what you mean by "serial order"? If you are implying that all MessageChannel does is process publications in a linear fashion, my for loop does that just fine. Does MessageChannel have a slightly more complex implementation?
  • not the channel puts it in a serial order, the fiber does.
    iterating and calling fiber.enqueue on each fiber does the same job.
    another nice feature about the channel (you keep refering to MessageChannel, that subclass exists only to keep track of the amount of messages being sent with counters) is that you can choose not to subscribe to every message that comes through, you can also decide to get just one every few seconds.
  • Boris wrote:
    not the channel puts it in a serial order, the fiber does.
    iterating and calling fiber.enqueue on each fiber does the same job.
    another nice feature about the channel (you keep refering to MessageChannel, that subclass exists only to keep track of the amount of messages being sent with counters) is that you can choose not to subscribe to every message that comes through, you can also decide to get just one every few seconds.
    I'm still learning, so I wasn't sure if I should use MessageChannel or it's base class. Since I don't care about counting I can use it's base now which is nice, so thank you for that information.

    Let me give you an example of what I'm doing and maybe you can tell me if I'm doing this right. Also keep in mind that I'm not using anything from Photon.SocketServer.Mmo, so any terminology here is my own and does not apply to any of your concepts.

    When a player joins a zone (zone would be what your World class is), every player already in that zone that is NOT the player that just joined (but is already subscribed to that zone's channel) will receive an event letting them know that this player joined and his initial position in the zone. Right now I do that via a for loop over my Peer objects and I call Peer.SendEvent() on each one. However, in my for loop, I skip the player that equals the player that just joined. Since I'm excluding one arbitrary peer from my list, I chose to use a for loop instead of going through the channel because I am not aware of any feature in the channel to allow me to omit a particular subscriber from receiving that published event.

    Is this the best way for this particular example?
  • sure, why not.. Lite does it this way, too.
    Another good solution would be to publish the join event before subscribing the channel.
    A third approach is including the sending peer with the join message and check on subscriber side whether to send it.