M:TG Game - Event Bussing

I've been pondering how to do some µObjects in a more intelligent system for a while.
I'm going to try to use Magic: The Gathering for this.

Much like the poke one; the idea here is to explore µObjects and how they can be applied in more situations.

With the M:TG example; I'm aiming to be able to play a game. Maybe not ALL cards or conditions; but... something.
Traditionally; there's a UI; so... not sure how that'll go as I'm not a huge UI fan. I think I have a little bit before I get there though.

In additon to µObjects as part of this experiment; I'm going to use microServices. MicroServices and µObejcts; should make for an interesting project. :)

Event Bus

I'm going to roll my own event bus and message objects for now. The bus is going to be a simple Observer patter. I don't need a lot. Things register and loop through them giving them the message.

I'll need to open a port so that a different client can attach; for debugging purposes. Though if I can make that work as two way chatter; actual playable games! Wooo!

Getting ahead of myself a bit.

I could use kafka or rabbit MQ... I just want something simple in my app. It doesn't need to be high volume.
The expectation is all microservices will be quick as well as "fire and forget" from the bus perspective.

There's not a lot of excitement happening here. I'm going through and µObjecting up an EventBus.

I'm getting better at sockets and threading. Well - Not Sockets. I'm using the TcpListener and TcpClient for the main interactions.

One of the more interesting things I'm working on here is how to a stream that's kept open.
I'm currently assuming perfection; and not dropped connections. :)
Right now I have it polling via a timer. I'd like to get in the async functionality and have it trigger when new content is put into the stream. Push vs Pull.
I have a functional pull mechanism. I think getting it to be push will require a bit of changes. I want to get the desired version into place first. If this wasn't a side project; maybe the pull mechanism could stay for a while.
The pulling mechanism is available in commit f4c3c61.

I cheered a little bit when I got it working. The data on my demo client/server project is pushed from both side.

I made sure it handled long messages. With a 256 buffer; wrote one that'd be read in 3 parts. Clients notified correctly!

I'm slowly turning it into µObjects. I don't think there's a "good" way to do this. It'll depend on the specific uses initally. Over time, the foundation will grow and there'll be a more OO representation of a Socket, but for now - Just what is needed.
I've spent a couple days working on the remote event bus stuff. I learned a lot through the process. Most of the time was figuring out how all the stuff works in a "test" project.

In commit 46fc741 I've got the Async version of the socket interaction working. There's... like... zero error handling here. It catches; probably writes to the Console.

This is forming the basis of the event bus I'll be using for communication between components.

The big reason I wanted to get the network event bus in place and functional is for a debugger. I can hook up a "DebugApp" that just displays the messages. It'll help me debug what's happening in the app. It'll eventually evolve into a fancy pants thing with filtering; but that's for later.

Left To Do

I've gotten it pretty well µObjected. There's a few sticklers I haven't ironed out. The Socket class being the big one. Once I iron that out; I think the rest of the stragglers will clean up nice.

I don't know when I'll clean the networking up entirely. It's a bit dirty in there. The interface is clean; so simple to use via behaviors.

One wonderful thing that happened while using µObjects to simplify the system. I've been using the Socket Code Examples to get a better understanding of the entire system. Which is what the past few days have been.

In the Async version; almost the Begin* methods all allow passing a state object through that's accessible to the Callback.

public IAsyncResult BeginReceive(
	byte[] buffer,
	int offset,
	int size,
	SocketFlags socketFlags,
	AsyncCallback callback,
	object state <-- This guy
)

The Async example has a databag with some fields; including the buffer information.
I don't need to pass a state object. There's one that I have to pass the client object through; but it should get cleaned up when I wrapp the Socket class.

The rest... The class has the callback. The call has all the fields needed. The callback has access to the class fields. I don't need the state object for most of the instances. Will need them even less once I wrap socket.

I'm kinda expecting to have to build my own "callback" process so that I can work around the expected limits of the IAsyncResult. Do something more class based... We'll see.

Summary

I've spent about a week churning on the networking bit for the event bus. While not perfect, I want to start in on some other aspects of the goal for this exercise.

I want to work on the Magic Cards as objects. I want to work on the IEventMessage to have attributes.
I want to build a EventBus client that will filter out messages unless they meet certain filters.

I'll also need to take another pass and write some test around some classes. Woooo!

For the event bus filtering; I want listeners to be able to filter out content. For example; the "Graveyard" listener might reject anything that doesn't have a "TargetField:Graveyard" attribute.
I don't know what they will look like - which is why I want to work on it some.

Show Comments