NanoStrand

Description

Smalltalk bindings for nanomsg

Details

Source
GitHub
License
MIT
Forks
1
Created
June 13, 2015
Updated
June 13, 2015

Categories

System / OS

README excerpt

# NanoStrand
Smalltalk bindings for [nanomsg](http://nanomsg.org).


##Overview
nanomsg is a simple, fast socket abstraction library that supports many communication patterns ("scalability protocols").

NanoStrand is a gate to the nanomsg world for Smalltalk users. Since there are many [language-bindings for nanomsg](http://nanomsg.org/documentation.html), integrations with other network programs would be much simpler via NanoStrand.

NanoStrand is composed of two-parts:

- A thin FFI wrapper of the nanomsg API (NanoStrand-FFI) 
- More "objectified" socket classes (NanoStrand-Core)

Currently FFI part is based on NativeBoost, so the main target is [Pharo Smalltalk](http://pharo.org). But the FFI part will be pluggable for supporting other Smalltalk dialects (Squeak, Cuis, VisualWorks, etc).

For MCZ packages, visit <a href="http://smalltalkhub.com/#!/~MasashiUmezawa/NanoStrand">SmalltalkHub NanoStrand site</a>.


##Installation
- Download and compile nanomsg.
	
	Please see [the instruction](http://nanomsg.org/download.html) in nanomsg site. You'll need 32-bit option (CFLAGS=-m32), if you use 32-bit Cog VM.

- Put the nanomsg shared library (so, dll, or dylib) to the VM directory.

- Load NanoStrand to Pharo.

```Smalltalk
Gofer new
      url: 'http://smalltalkhub.com/mc/MasashiUmezawa/NanoStrand/main';
      package: 'ConfigurationOfNanoStrand';
      load.
(Smalltalk at: #ConfigurationOfNanoStrand) load
```

##Examples

###Simple PULL / PUSH on one node
```Smalltalk
[[
"Setup PULL socket"
sock1 := NnPullSocket withBind: 'tcp://*:5575'.
sock1 onReceiveReady: [:sock | Transcript cr; show: '#PULL: ', sock receive asString].

"Setup PUSH socket"
sock2 := NnPushSocket withConnect: 'tcp://127.0.0.1:5575'.
sock2 onSendReady: [:sock | sock send: '#PUSH: ', Time now asString].

"Start a Poller for multiplexing"
poller := NnPoller startWithSockets: {sock1. sock2}.

1 seconds wait. "The process ends after a second"

] ensure: [
poller stopAndCloseSockets.
]] fork.
```

Let's try changing the source to accumulate the result to an OrderedCollection:

```Smalltalk
"Setup PULL socket"
ord := OrderedCollection new.
sock1 := NnPullSocket withBind: 'tcp://*:5575'.
sock1 onReceiveReady: [:sock | ord add: (sock receive asString)].
``` 

After running the program, we can see how many messages were processed.

```Smalltalk
"print it"
ord size. "=> 22852"
```

22852 messages per second on my MBA! It is pretty fast.


###PULL + PUB server connected with PUSH / SUB multi clients

####Server - PULL + PUB
 This Smalltalk server pulls the messages from clients and pushes 'rem' events.

```Smalltalk
[[
received := OrderedCollection new. "A message box"

"Setup PULL socket"
sock1 := NnPullSocket withBind: 'tcp://127.0.0.1:5585'.
sock1 onReceiveReady: [:sock | | rec |
	rec := (sock receiveFor: 200 timeoutDo: ['']) asString.
	rec ifNotEmpty: [
		received add: rec. "Stock the received message"
		Transcript cr; show: 'Received:', rec, ':', Time now asString].
].

"Setup PUB socket"
sock2 := NnPubSocket withBind: 'tcp://127.0.0.1:5586'.
sock2 onSendReady: [:sock | |rem |
	rem := received size rem: 10. "Compute the rem:10 of the messages."
	
	"If rem is 0 or 5, publish the events."
	rem = 0 ifTrue: [sock send: 'Evt:Rem0:', Time now asString].
	rem = 5 ifTrue: [sock send: 'Evt:Rem5:', Time now asString].
].

poller := NnPoller new.
poller startWithSockets: {sock1. sock2}.

30 seconds wait. "The demo server ends after 30 seconds. So, be quick!"

] ensure: [
poller stopAndCloseSockets.
]] fork.

```

For clients, we use [nanocat](http://nanomsg.org/v0.5/nanocat.1.html). An official command line client of nanomsg (in C).

####Client 1 - PUSH
Pushes "HelloWorld" messages periodically.

```
$ nanocat --push --connect tcp://127.0.0.1:5585 --data HelloWorld -i 1
```

####Client 2 - SUB
Subscribes to all events.

```
$ nanocat --sub --connect tcp://127.0.0.1:5586 -A
```

####Client 3 - SUB
Subscribes to 'Event:Rem0' only.

```
$ nanocat --sub --connect tcp://127.0.0.1:5586 --subscribe Evt:Rem0 -A
```

Now you can see that after Client 1's messages are stocked on server, Rem0 & Rem5 events will be delivered to Clients 2, and Rem0 events will be delivered to Client 3.

← Back to results