|
| 1 | +NodeSocket for NodeJS |
| 2 | +== |
| 3 | + |
| 4 | +A network protocol for an execution space amongst application instances, via a slave to master relationship. |
| 5 | + |
| 6 | +Server |
| 7 | +-- |
| 8 | +```JavaScript |
| 9 | +var nodesocket = require('nodesocket'); |
| 10 | +var server = nodesocket().createServer(8080, 'localhost'); |
| 11 | + |
| 12 | +server.defineFunction('remoteFunction', function() { |
| 13 | + console.log('Executed on the server. Closing...'); |
| 14 | + server.close(); |
| 15 | +}); |
| 16 | + |
| 17 | +server.start(); |
| 18 | +``` |
| 19 | +By default, the server node is configured to be the slave, receiving function calls from the client. |
| 20 | +Calling `defineFunction` configures the server instance to call the passed callback when that specific command is received from a client (master). |
| 21 | + |
| 22 | +Client |
| 23 | +-- |
| 24 | +```JavaScript |
| 25 | +var nodesocket = require('nodesocket'); |
| 26 | +var client = nodesocket().createClient(8080, 'localhost'); |
| 27 | + |
| 28 | +var remoteFunction = client.linkFunction('remoteFunction'); |
| 29 | + |
| 30 | +client.on('verified', function() { |
| 31 | + remoteFunction(function() { |
| 32 | + console.log('Function returned. Closing...'); |
| 33 | + client.close(); |
| 34 | + }); |
| 35 | +}); |
| 36 | + |
| 37 | +client.connect(); |
| 38 | +``` |
| 39 | +Once the server is setup to receive a function called `'remoteFunction'`, you can create a 'linked' function by calling the appropriately named `linkFunction` function. |
| 40 | +The process of connecting a client a server is slightly different because first the server must be verified as a NodeSocket node (when acting as a master). This is handled via the `'verified'` event that is raised. |
| 41 | +Once verified, the client and server being 'talking' to each other in a language they both understand (being the NodeSocket protocol). |
| 42 | + |
| 43 | +Switching Roles |
| 44 | +== |
| 45 | +By default the client's role is the master and the server is the slave, but these roles can be reversed, allowing the server to call functions residing on the client node. |
| 46 | + |
| 47 | +As a client: |
| 48 | +```JavaScript |
| 49 | +client.defineFunction('remoteFunction', function() { |
| 50 | + console.log('Executed on the client. Closing...'); |
| 51 | + client.close(); |
| 52 | +}); |
| 53 | + |
| 54 | +client.on('verified', function() { |
| 55 | + client.requestSlave(); // Tells server to take the reigns |
| 56 | +}); |
| 57 | +``` |
| 58 | + |
| 59 | +To handle this request on the server: |
| 60 | + |
| 61 | +```JavaScript |
| 62 | +server.on('masterRequest', function(client) { |
| 63 | + var remoteFunction = client.linkFunction('remoteFunction'); |
| 64 | + remoteFunction(function() { |
| 65 | + console.log('Function returned. Closing...'); |
| 66 | + server.close(); |
| 67 | + }); |
| 68 | +}); |
| 69 | +``` |
| 70 | + |
| 71 | +It's also possible for a server to request to become the master, without the clients initiative: |
| 72 | + |
| 73 | +```JavaScript |
| 74 | +server.on('verified', function(client) { |
| 75 | + client.requestMaster(); |
| 76 | +}); |
| 77 | + |
| 78 | +server.on('masterRequest', function(client) { |
| 79 | + // etc... |
| 80 | +}); |
| 81 | +``` |
| 82 | + |
| 83 | +For security reasons it's also possible for a client to disable a remote becoming the master by passing the `denyMasterRequests: true` option in the `nodesocket` initializer: |
| 84 | + |
| 85 | +```JavaScript |
| 86 | +var nodesocket = require('nodesocket'); |
| 87 | +var client = nodesocket({ |
| 88 | + denyMasterRequests: true |
| 89 | +}).createClient(8080, 'localhost'); |
| 90 | +``` |
| 91 | + |
| 92 | +Passing Arguments |
| 93 | +== |
| 94 | +Passing arguments to a master function is incredibly simple, with almost no strings attached. |
| 95 | + |
| 96 | +Client example: |
| 97 | +```JavaScript |
| 98 | +var remoteFunction = client.linkFunction('remoteFunction'); |
| 99 | + |
| 100 | +client.on('verified', function() { |
| 101 | + remoteFunction(function(result) { |
| 102 | + console.log('Result: ' + result); |
| 103 | + }, 'this is a parameter', 12.5, 10, true); |
| 104 | + /* Will output: |
| 105 | + Result: 125 |
| 106 | + */ |
| 107 | +}); |
| 108 | +``` |
| 109 | + |
| 110 | +Server example: |
| 111 | +```JavaScript |
| 112 | +server.defineFunction('remoteFunction', function(s, f, n, b) { |
| 113 | + console.log('The following parameters were passed:'); |
| 114 | + for(var arg in arguments) { |
| 115 | + console.log(arg + ': ' + arguments[arg]); |
| 116 | + } |
| 117 | + |
| 118 | + return n * f; |
| 119 | + |
| 120 | + /* Will output: |
| 121 | + 0: this is a parameter |
| 122 | + 1: 12.5 |
| 123 | + 2: 10 |
| 124 | + 3: true |
| 125 | + */ |
| 126 | +}); |
| 127 | +``` |
| 128 | + |
| 129 | +Type Mapping |
| 130 | +-- |
| 131 | + |
| 132 | +Depending on the use, there may come a time when a specific datatype will be needed when passed to a linked function. These are taken care of during the initial function link, like so: |
| 133 | + |
| 134 | +```JavaScript |
| 135 | +var example = client.linkFunction('example', [ |
| 136 | + '0': 'string', |
| 137 | + '1': 'uint', |
| 138 | + '2': 'double', |
| 139 | + // etc... |
| 140 | +]); |
| 141 | +``` |
| 142 | + |
| 143 | +This allows to sending of the right datatype, because otherwise defaults will be used and cached for future calls to the remote function (for performance reasons). |
| 144 | + |
| 145 | +When defining a function, you can do the same with the return datatype: |
| 146 | + |
| 147 | +```JavaScript |
| 148 | +server.defineFunction('example', function(s, ui, d) { |
| 149 | + return 10.25; |
| 150 | +}, 'float'); |
| 151 | +``` |
| 152 | + |
| 153 | +**Data types:** |
| 154 | + |
| 155 | +>byte |
| 156 | +ubyte |
| 157 | +short |
| 158 | +ushort |
| 159 | +int |
| 160 | +uint |
| 161 | +float |
| 162 | +double |
| 163 | +string |
| 164 | +boolean |
| 165 | + |
| 166 | +*Note:* The current version of the NodeSocket protocol **does not** support arrays. If use of arrays are required, you can use the `apply` function for serialize/deserialize to JSON. |
| 167 | + |
| 168 | +WebSocket Support |
| 169 | +== |
| 170 | +A WebSocket capable server can be configured by passing the `webSocket: true` option in the `nodesocket` initializer. You can also require that the requested host match the host/IP that the server is bound to with `webSocketVerifyHost: true`. |
| 171 | + |
| 172 | +```JavaScript |
| 173 | +var server = nodesocket({ |
| 174 | + webSocket: true, |
| 175 | + webSocketVerifyHost: true /* Requires hostname to match 'localhost' */ |
| 176 | +}).createServer(8080, 'localhost'); |
| 177 | +``` |
| 178 | + |
| 179 | +The web browser implementation for the NodeSocket protocol can be found here: https://github.com/bryanwayb/nodesocket-browserify |
| 180 | + |
| 181 | +SSL/TLS |
| 182 | +== |
| 183 | +Encrypted communication is also possible. To enable, pass `secure: true` to the `nodesocket` initializer options, as well as any options that would normally be passed to the NodeJS TLS/SSL API for configuration, as those options are passed through. |
| 184 | + |
| 185 | +For a full list of the available configuration options, check out the NodeJS API documentation for [servers](https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener) and [clients](https://nodejs.org/api/tls.html#tls_tls_connect_port_host_options_callback). |
0 commit comments