Installations
npm install seneca-transport
Developer Guide
Typescript
No
Module System
CommonJS
Node Version
20.11.1
NPM Version
10.2.4
Score
56.5
Supply Chain
98.7
Quality
79.9
Maintenance
100
Vulnerability
98.2
License
Releases
Contributors
Unable to fetch Contributors
Languages
JavaScript (98.8%)
Shell (0.91%)
Dockerfile (0.29%)
Developer
senecajs
Download Statistics
Total Downloads
4,165,225
Last Day
405
Last Week
5,555
Last Month
33,304
Last Year
506,436
GitHub Statistics
63 Stars
370 Commits
44 Forks
13 Watching
6 Branches
26 Contributors
Package Meta Information
Latest Version
8.3.0
Package Id
seneca-transport@8.3.0
Unpacked Size
71.79 kB
Size
20.67 kB
File Count
7
NPM Version
10.2.4
Node Version
20.11.1
Publised On
14 Oct 2024
Total Downloads
Cumulative downloads
Total Downloads
4,165,225
Last day
-63.7%
405
Compared to previous day
Last week
-19.4%
5,555
Compared to previous week
Last month
15%
33,304
Compared to previous month
Last year
-21.8%
506,436
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Peer Dependencies
2
A Seneca.js transport plugin
This open source module is sponsored and supported by Voxgig. |
---|
seneca-transport
Description
This plugin provides the HTTP/HTTPS and TCP transport channels for micro-service messages. It's a built-in dependency of the Seneca module, so you don't need to include it manually. You use this plugin to wire up your micro-services so that they can talk to each other.
seneca-transport's source can be read in an annotated fashion by:
- running
npm run annotate
- viewing ./docs/annotated/transport.html locally
If you're using this module, and need help, you can:
- Post a github issue,
- Tweet to @senecajs,
- Ask on the Gitter.
If you are new to Seneca in general, please take a look at senecajs.org. We have everything from tutorials to sample apps to help get you up and running quickly.
Seneca compatibility
Supports Seneca versions 3.x and above.
Install
This plugin module is included in the main Seneca module:
1npm install seneca
To install separately, use:
1npm install seneca-transport
Quick Example
Let's do everything in one script to begin with. You'll define a simple Seneca plugin that returns the hex value of color words. In fact, all it can handle is the color red!
You define the action pattern color:red, which always returns the
result {hex:'#FF0000'}
. You're also using the name of the
function color to define the name of the plugin (see How to write a
Seneca plugin).
1function color() { 2 this.add( 'color:red', function(args,done){ 3 done(null, {hex:'#FF0000'}); 4 }) 5}
Now, let's create a server and client. The server Seneca instance will load the color plugin and start a web server to listen for inbound messages. The client Seneca instance will submit a color:red message to the server.
1var seneca = require('seneca') 2 3seneca() 4 .use(color) 5 .listen() 6 7seneca() 8 .client() 9 .act('color:red')
Example with HTTPS:
To enable HTTPS, pass an options object to the listen
function setting the protocol
option to 'https' and provide a serverOptions
object with key
and cert
properties.
1var seneca = require('seneca') 2var Fs = require('fs') 3 4 5seneca() 6 .use(color) 7 .listen({ 8 type: 'http', 9 port: '8000', 10 host: 'localhost', 11 protocol: 'https', 12 serverOptions : { 13 key : Fs.readFileSync('path/to/key.pem', 'utf8'), 14 cert : Fs.readFileSync('path/to/cert.pem', 'utf8') 15 } 16 }) 17 18seneca() 19 .client({ 20 type: 'http', 21 port: '8000', 22 host: 'localhost', 23 protocol: 'https' 24 }) 25 .act('color:red')
You can create multiple instances of Seneca inside the same Node.js process. They won't interfere with each other, but they will share external options from configuration files or the command line.
If you run the full script (full source is in readme-color.js), you'll see the standard Seneca startup log messages, but you won't see anything that tells you what the color plugin is doing since this code doesn't bother printing the result of the action. Let's use a filtered log to output the inbound and outbound action messages from each Seneca instance so we can see what's going on. Run the script with:
1node readme-color.js --seneca.log=type:act,regex:color:red
NOTE: when running the examples in this documentation, you'll find that most of the Node.js processes do not exit. This because they running in server mode. You'll need to kill all the Node.js processes between execution runs. The quickest way to do this is:
1$ killall node
This log filter restricts printed log entries to those that report
inbound and outbound actions, and further, to those log lines that
match the regular expression /color:red/
. Here's what
you'll see:
1[TIME] vy../..15/- DEBUG act - - IN 485n.. color:red {color=red} CLIENT 2[TIME] ly../..80/- DEBUG act color - IN 485n.. color:red {color=red} f2rv.. 3[TIME] ly../..80/- DEBUG act color - OUT 485n.. color:red {hex=#FF0000} f2rv.. 4[TIME] vy../..15/- DEBUG act - - OUT 485n.. color:red {hex=#FF0000} CLIENT
The second field is the identifier of the Seneca instance. You can see
that first the client (with an identifier of vy../..15/-) sends the
message {color=red}
. The message is sent over HTTP to the
server (which has an identifier of ly../..80/-). The server performs the
action, generating the result {hex=#FF0000}
, and sends
it back.
The third field, DEBUG
, indicates the log level. The next
field, act
indicates the type of the log entry. Since
you specified type:act
in the log filter, you've got a
match!
The next two fields indicate the plugin name and tag, in this case color
-
. The plugin is only known on the server side, so the client
just indicates a blank entry with -
. For more details on
plugin names and tags, see How to write a Seneca
plugin.
The next field (also known as the case) is either IN
or
OUT
, and indicates the direction of the message. If you
follow the flow, you can see that the message is first inbound to the
client, and then inbound to the server (the client sends it
onwards). The response is outbound from the server, and then outbound
from the client (back to your own code). The field after that,
485n..
, is the message identifier. You can see that it
remains the same over multiple Seneca instances. This helps you to
debug message flow.
The next two fields show the action pattern of the message,
color:red
, followed by the actual data of the request
message (when inbound), or the response message (when outbound).
The last field f2rv..
is the internal identifier of the
action function that acts on the message. On the client side, there is
no action function, and this is indicated by the CLIENT
marker. If you'd like to match up the action function identifier to
message executions, add a log filter to see them:
node readme-color.js --seneca.log=type:act,regex:color:red \
--seneca.log=plugin:color,case:ADD
[TIME] ly../..80/- DEBUG plugin color - ADD f2rv.. color:red
[TIME] vy../..15/- DEBUG act - - IN 485n.. color:red {color=red} CLIENT
[TIME] ly../..80/- DEBUG act color - IN 485n.. color:red {color=red} f2rv..
[TIME] ly../..80/- DEBUG act color - OUT 485n.. color:red {hex=#FF0000} f2rv..
[TIME] vy../..15/- DEBUG act - - OUT 485n.. color:red {hex=#FF0000} CLIENT
The filter plugin:color,case:ADD
picks out log entries of
type plugin, where the plugin has the name color, and where the
case is ADD. These entries indicate the action patterns that a
plugin has registered. In this case, there's only one, color:red.
You've run this example in a single Node.js process up to now. Of course, the whole point is to run it in separate processes! Let's do that. First, here's the server:
1function color() { 2 this.add( 'color:red', function(args,done){ 3 done(null, {hex:'#FF0000'}); 4 }) 5} 6 7var seneca = require('seneca') 8 9seneca() 10 .use(color) 11 .listen()
Run this in one terminal window with:
1$ node readme-color-service.js --seneca.log=type:act,regex:color:red
And on the client side:
1var seneca = require('seneca') 2 3seneca() 4 .client() 5 .act('color:red')
And run with:
1$ node readme-color-client.js --seneca.log=type:act,regex:color:red
You'll see the same log lines as before, just split over the two processes. The full source code is the test folder.
Non-Seneca Clients
The default transport mechanism for messages is HTTP. This means you can communicate easily with a Seneca micro-service from other platforms. By default, the listen
method starts a web server on port 10101, listening on all interfaces. If you run the readme-color-service.js script again (as above), you can talk to it by POSTing JSON data to the /act
path. Here's an example using the command line curl utility.
1$ curl -d '{"color":"red"}' http://localhost:10101/act 2{"hex":"#FF0000"}
If you dump the response headers, you'll see some additional headers that give you contextual information. Let's use the -v
option of curl to see them:
1$ curl -d '{"color":"red"}' -v http://localhost:10101/act 2... 3* Connected to localhost (127.0.0.1) port 10101 (#0) 4> POST /act HTTP/1.1 5> User-Agent: curl/7.30.0 6> Host: localhost:10101 7> Accept: */* 8> Content-Length: 15 9> Content-Type: application/x-www-form-urlencoded 10> 11* upload completely sent off: 15 out of 15 bytes 12< HTTP/1.1 200 OK 13< Content-Type: application/json 14< Cache-Control: private, max-age=0, no-cache, no-store 15< Content-Length: 17 16< seneca-id: 9wu80xdsn1nu 17< seneca-kind: res 18< seneca-origin: curl/7.30.0 19< seneca-accept: sk5mjwcxxpvh/1409222334824/- 20< seneca-time-client-sent: 1409222493910 21< seneca-time-listen-recv: 1409222493910 22< seneca-time-listen-sent: 1409222493910 23< Date: Thu, 28 Aug 2014 10:41:33 GMT 24< Connection: keep-alive 25< 26* Connection #0 to host localhost left intact 27{"hex":"#FF0000"}
You can get the message identifier from the seneca-id header, and the identifier of the Seneca instance from seneca-accept.
There are two structures that the submitted JSON document can take:
- Vanilla JSON containing your request message, plain and simple, as per the example above,
- OR: A JSON wrapper containing the client details along with the message data.
The JSON wrapper follows the standard form of Seneca messages used in other contexts, such as message queue transports. However, the simple vanilla format is perfectly valid and provided explicitly for integration. The wrapper format is described below.
If you need Seneca to listen on a particular port or host, you can
specify these as options to the listen
method. Both are
optional.
1seneca() 2 .listen( { host:'192.168.1.2', port:80 } )
On the client side, either with your own code, or the Seneca client, you'll need to use matching host and port options.
1$ curl -d '{"color":"red"}' http://192.168.1.2:80/act
1seneca() 2 .client( { host:'192.168.1.2', port:80 } )
You can also set the host and port via the Seneca options facility. When
using the options facility, you are setting the default options for
all message transports. These can be overridden by arguments to individual
listen
and client
calls.
Let's run the color example again, but with a different port. On the server-side:
1$ node readme-color-service.js --seneca.log=type:act,regex:color:red \ 2 --seneca.options.transport.port=8888
And the client-side:
1curl -d '{"color":"red"}' -v http://localhost:8888/act
OR
1$ node readme-color-client.js --seneca.log=type:act,regex:color:red \ 2 --seneca.options.transport.port=8888
Using the TCP Channel
Also included in this plugin is a TCP transport mechanism. The HTTP mechanism offers easy integration, but it is necessarily slower. The TCP transport opens a direct TCP connection to the server. The connection remains open, avoiding connection overhead for each message. The client side of the TCP transport will also attempt to reconnect if the connection breaks, providing fault tolerance for server restarts.
To use the TCP transport, specify a type property to the
listen
and client
methods, and give it the
value tcp. Here's the single script example again:
1seneca() 2 .use(color) 3 .listen({type:'tcp'}) 4 5seneca() 6 .client({type:'tcp'}) 7 .act('color:red')
The full source code is in the readme-color-tcp.js file. When you run this script it would be great to verify that the right transport channels are being created. You'd like to see the configuration, and any connections that occur. By default, this information is printed with a log level of INFO, so you will see it if you don't use any log filters.
Of course, we are using a log filter. So let's add another one to print the connection details so we can sanity check the system. We want to print any log entries with a log level of INFO. Here's the command:
1$ node readme-color-tcp.js --seneca.log=level:INFO \ 2 --seneca.log=type:act,regex:color:red
This produces the log output:
1[TIME] 6g../..49/- INFO hello Seneca/0.5.20/6g../..49/- 2[TIME] f1../..79/- INFO hello Seneca/0.5.20/f1../..79/- 3[TIME] f1../..79/- DEBUG act - - IN wdfw.. color:red {color=red} CLIENT 4[TIME] 6g../..49/- INFO plugin transport - ACT b01d.. listen open {type=tcp,host=0.0.0.0,port=10201,...} 5[TIME] f1../..79/- INFO plugin transport - ACT nid1.. client {type=tcp,host=0.0.0.0,port=10201,...} any 6[TIME] 6g../..49/- INFO plugin transport - ACT b01d.. listen connection {type=tcp,host=0.0.0.0,port=10201,...} remote 127.0.0.1 52938 7[TIME] 6g../..49/- DEBUG act color - IN bpwi.. color:red {color=red} mcx8i4slu68z UNGATE 8[TIME] 6g../..49/- DEBUG act color - OUT bpwi.. color:red {hex=#FF0000} mcx8i4slu68z 9[TIME] f1../..79/- DEBUG act - - OUT wdfw.. color:red {hex=#FF0000} CLIENT
The inbound and outbound log entries are as before. In addition, you
can see the INFO level entries. At startup, Seneca logs a "hello"
entry with the identifier of the current instance execution. This
identifier has the form:
Seneca/[version]/[12-random-chars]/[timestamp]/[tag]
. This
identifier can be used for debugging multi-process message flows. The
second part is a local timestamp. The third is an optional tag, which
you could provide with seneca({tag:'foo'})
, although we
don't use tags in this example.
There are three INFO level entries of interest. On the server-side, the listen facility logs the fact that it has opened a TCP port, and is now listening for connections. Then the client-side logs that it has opened a connection to the server. And finally the server logs the same thing.
As with the HTTP transport example above, you can split this code into two processes by separating the client and server code. Here's the server:
1function color() { 2 this.add( 'color:red', function(args,done){ 3 done(null, {hex:'#FF0000'}); 4 }) 5} 6 7var seneca = require('seneca') 8 9seneca() 10 .use(color) 11 .listen({type:'tcp'})
And here's the client:
1seneca() 2 .client({type:'tcp'}) 3 .act('color:red')
You can cheat by running the HTTP examples with the additional command
line option: --seneca.options.transport.type=tcp
.
To communicate with a Seneca instance over TCP, you can send a message from the command line that Seneca understands:
1# call the color:red action pattern 2echo '{"id":"w91/enj","kind":"act","origin":"h5x/146/..77/-","act":{"color":"red"},"sync":true}' | nc 127.0.0.1 10201 3
Seneca answers with a message like:
1{"id":"w91/enj","kind":"res","origin":"h5x/146/..77/-","accept":"bj../14../..47/-","time":{"client_sent":..,"listen_recv":..,"listen_sent":..},"sync":true,"res":{"hex":"#FF0000"}} 2# the produced result is in the "res" field
HTTP and TCP are not the only transport mechanisms available. Of course, in true Seneca-style, the other mechanisms are available as plugins. Here's the list.
- redis-transport: uses redis for a pub-sub message distribution model
- beanstalk-transport: uses beanstalkd for a message queue
- balance-client: a load-balancing client transport over multiple Seneca listeners
If you're written your own transport plugin (see below for instructions), and want to have it listed here, please submit a pull request.
Multiple Channels
You can use multiple listen
and client
definitions on the same Seneca instance, in any order. By default, a
single client
definition will send all unrecognized
action patterns over the network. When you have multiple client
definitions, it's becuase you want to send some action patterns to one
micro-service, and other patterns to other micro-services. To do this,
you need to specify the patterns you are interested in. In Seneca,
this is done with a pin
.
A Seneca pin
is a pattern for action patterns. You provide a list of
property names and values that must match. Unlike ordinary action
patterns, where the values are fixed, with a pin
, you can use globs
to match more than one value. For example, let's say you have the patterns:
foo:1,bar:zed-aaa
foo:1,bar:zed-bbb
foo:1,bar:zed-ccc
Then you can use these pins
to pick out the patterns you want:
- The pin
foo:1
matches the patternsfoo:1,bar:zed-aaa
andfoo:1,bar:zed-bbb
andfoo:1,bar:zed-ccc
- The pin
foo:1, bar:*
also matches the patternsfoo:1,bar:zed-aaa
andfoo:1,bar:zed-bbb
andfoo:1,bar:zed-ccc
- The pin
foo:1, bar:*-aaa
matches only the patternfoo:1,bar:zed-aaa
Let's extend the color service example. You'll have three separate services, all running in separate processes. They will listen on ports 8081, 8082, and 8083 respectively. You'll use command line arguments for settings. Here's the service code (see readme-many-colors-server.js):
1var color = process.argv[2] 2var hexval = process.argv[3] 3var port = process.argv[4] 4 5var seneca = require('seneca') 6 7seneca() 8 9 .add( 'color:'+color, function(args,done){ 10 done(null, {hex:'#'+hexval}); 11 }) 12 13 .listen( port ) 14 15 .log.info('color',color,hexval,port)
This service takes in a color name, a color hexadecimal value, and a
port number from the command line. You can also see how the listen
method can take a single argument, the port number. To offer the
color:red service, run this script with:
1$ node readme-many-colors-server.js red FF0000 8081
And you can test with:
1$ curl -d '{"color":"red"}' http://localhost:8081/act
Of course, you need to use some log filters to pick out the activity
you're interested in. In this case, you've used a
log.info
call to dump out settings. You'll also want to
see the actions as the occur. Try this:
1node readme-many-colors-server.js red FF0000 8081 --seneca.log=level:info \ 2 --seneca.log=type:act,regex:color
And you'll get:
1[TIME] mi../..66/- INFO hello Seneca/0.5.20/mi../..66/- 2[TIME] mi../..66/- INFO color red FF0000 8081 3[TIME] mi../..66/- INFO plugin transport - ACT 7j.. listen {type=web,port=8081,host=0.0.0.0,path=/act,protocol=http,timeout=32778,msgprefix=seneca_,callmax=111111,msgidlen=12,role=transport,hook=listen} 4[TIME] mi../..66/- DEBUG act - - IN ux.. color:red {color=red} 9l.. 5[TIME] mi../..66/- DEBUG act - - OUT ux.. color:red {hex=#FF0000} 9l..
You can see the custom INFO log entry at the top, and also the transport settings after that.
Let's run three of these servers, one each for red, green and blue. Let's also run a client to connect to them.
Let's make it interesting. The client will listen
so that it can
handle incoming actions, and pass them on to the appropriate server by
using a pin
. The client will also define a new action that can
aggregate color lookups.
1var seneca = require('seneca') 2 3seneca() 4 5 // send matching actions out over the network 6 .client({ port:8081, pin:'color:red' }) 7 .client({ port:8082, pin:'color:green' }) 8 .client({ port:8083, pin:'color:blue' }) 9 10 // an aggregration action that calls other actions 11 .add( 'list:colors', function( args, done ){ 12 var seneca = this 13 var colors = {} 14 15 args.names.forEach(function( name ){ 16 seneca.act({color:name}, function(err, result){ 17 if( err ) return done(err); 18 19 colors[name] = result.hex 20 if( Object.keys(colors).length == args.names.length ) { 21 return done(null,colors) 22 } 23 }) 24 }) 25 26 }) 27 28 .listen() 29 30 // this is a sanity check 31 .act({list:'colors',names:['blue','green','red']},console.log)
This code calls the client
method three times. Each time,
it specifies an action pattern pin
, and a destination port. And
action submitted to this Seneca instance via the act
method will be matched against these pin
patterns. If there is a
match, they will not be processed locally. Instead they will be sent
out over the network to the micro-service that deals with them.
In this code, you are using the default HTTP transport, and just changing the port number to connect to. This reflects the fact that each color micro-service runs on a separate port.
The listen
call at the bottom makes this "client" also
listen for inbound messages. So if you run, say the color:red
service, and also run the client, then you can send color:red messages
to the client.
You need to run four processes:
1node readme-many-colors-server.js red FF0000 8081 --seneca.log=level:info --seneca.log=type:act,regex:color & 2node readme-many-colors-server.js green 00FF00 8082 --seneca.log=level:info --seneca.log=type:act,regex:color & 3node readme-many-colors-server.js blue 0000FF 8083 --seneca.log=level:info --seneca.log=type:act,regex:color & 4node readme-many-colors-client.js --seneca.log=type:act,regex:CLIENT & 5
And then you can test with:
1$ curl -d '{"color":"red"}' http://localhost:10101/act 2$ curl -d '{"color":"green"}' http://localhost:10101/act 3$ curl -d '{"color":"blue"}' http://localhost:10101/act
These commands are all going via the client, which is listening on port 10101.
The client code also includes an aggregation action, list:colors. This lets you call multiple color actions and return one result. This is a common micro-service pattern.
The script readme-many-colors.sh wraps all this up into one place for you so that it is easy to run.
Seneca does not require you to use message transports. You can run everything in one process. But when the time comes, and you need to scale, or you need to break out micro-services, you have the option to do so.
Message Protocols
There is no message protocol as such, as the data representation of the underlying message transport is used. However, the plain text message representation is JSON in all known transports.
For the HTTP transport, message data is encoded as per the HTTP protocol. For the TCP transport, UTF8 JSON is used, with one well-formed JSON object per line (with a single "\n" as line terminator).
For other transports, please see the documentation for the underlying protocol. In general the transport plugins, such as seneca-redis-transport will handle this for you so that you only have to think in terms of JavaScript objects.
The JSON object is a wrapper for the message data. The wrapper contains some tracking fields to make debugging easier. These are:
- id: action identifier (appears in Seneca logs after IN/OUT)
- kind: 'act' for inbound actions, 'res' for outbound responses
- origin: identifier of orginating Seneca instance, where action is submitted
- accept: identifier of accepting Seneca instance, where action is performed
- time:
- client_sent: client timestamp when message sent
- listen_recv: server timestamp when message received
- listen_sent: server timestamp when response sent
- client_recv: client timestamp when response received
- act: action message data, as submitted to Seneca
- res: response message data, as provided by Seneca
- error: error message, if any
- input: input generating error, if any
Writing Your Own Transport
To write your own transport, the best approach is to copy one of the existing ones:
- transport.js: disconnected or point-to-point
- redis-transport.js: publish/subscribe
- beanstalk-transport.js: message queue
Choose a type for your transport, say "foo". You will need to implement two patterns:
- role:transport, hook:listen, type:foo
- role:transport, hook:client, type:foo
Rather than writing all of the code yourself, and dealing with all the messy details, you can take advantage of the built-in message serialization and error handling by using the utility functions that the transport plugin exports. These utility functions can be called in a specific sequence, providing a template for the implementation of a message transport:
The transport utility functions provide the concept of topics. Each message pattern is encoded as a topic string (alphanumeric) that could be used with a message queue server. You do not need to use topics, but they can be convenient to separate message flows.
To implement the client, use the template:
1var transport_utils = seneca.export('transport/utils')
2
3function hook_client_redis( args, clientdone ) {
4 var seneca = this
5 var type = args.type
6
7 // get your transport type default options
8 var client_options = seneca.util.clean(_.extend({},options[type],args))
9
10 transport_utils.make_client( make_send, client_options, clientdone )
11
12 // implement your transport here
13 // see an existing transport for full example
14 // make_send is called per topic
15 function make_send( spec, topic, send_done ) {
16
17 // setup topic in transport mechanism
18
19 // send the args over the transport
20 send_done( null, function( args, done ) {
21
22 // create message JSON
23 var outbound_message = transport_utils.prepare_request( seneca, args, done )
24
25 // send JSON using your transport API
26
27 // don't call done - that only happens if there's a response!
28 // this will be done for you
29 })
30 }
31}
To implement the server, use the template:
1var transport_utils = seneca.export('transport/utils')
2
3function hook_listen_redis( args, done ) {
4 var seneca = this
5 var type = args.type
6
7 // get your transport type default options
8 var listen_options = seneca.util.clean(_.extend({},options[type],args))
9
10 // get the list of topics
11 var topics = tu.listen_topics( seneca, args, listen_options )
12
13 topics.forEach( function(topic) {
14
15 // "listen" on the topic - implementation dependent!
16
17 // handle inbound messages
18 transport_utils.handle_request( seneca, data, listen_options, function(out){
19
20 // there may be no result!
21 if( null == out ) return ...;
22
23 // otherwise, send the result back
24 // don't forget to stringifyJSON(out) if necessary
25 })
26 })
27}
If you do not wish to use a template, you can implement transports using entirely custom code. In this case, you need to need to provide results from the hook actions. For the role:transport,hook:listen action, this is easy, as no result is required. For role:transport,hook:client, you need to provide an object with properties:
id
: an identifier for the clienttoString
: a string description for debug logsmatch( args )
: return true if the client can transport the given args (i.e. they match the client action pattern)send( args, done )
: a function that performs the transport, and callsdone
with the result when received
See the make_anyclient
and make_pinclient
functions in
transport.js for implementation examples.
Message transport code should be written very carefully as it will be subject to high load and many error conditions.
Plugin Options
The transport plugin family uses an extension to the normal Seneca
options facility. As well as supporting the standard method for
defining options (see How to Write a
Plugin), you can
also supply options via arguments to the client
or
listen
methods, and via the type name of the transport
under the top-level transport property.
The primary options are:
- msgprefix: a string to prefix to topic names so that they are namespaced
- callmax: the maximum number of in-flight request/response messages to cache
- msgidlen: length of the message indentifier string
These can be set within the top-level transport property of the main Seneca options tree:
1var seneca = require('seneca') 2seneca({ 3 transport:{ 4 msgprefix:'foo' 5 } 6})
Each transport type forms a sub-level within the transport option. The recognized types depend on the transport plugins you have loaded. By default, web and tcp are available. To use redis, for example, you need to do this:
1var seneca = require('seneca') 2seneca({ 3 transport:{ 4 redis:{ 5 timeout:500 6 } 7 } 8 }) 9 10 // assumes npm install seneca-redis-transport 11 .use('redis-transport') 12 13 .listen({type:'redis'})
You can set transport-level options inside the type property:
1var seneca = require('seneca') 2seneca({ 3 transport:{ 4 tcp:{ 5 timeout:1000 6 } 7 } 8})
The transport-level options vary by transport. Here are the default ones for HTTP:
- type: type name; constant: 'web'
- port: port number; default: 10101
- host: hostname; default: '0.0.0.0' (all interfaces)
- path: URL path to submit messages; default: '/act'
- protocol: HTTP protocol; default 'http'
- timeout: timeout in milliseconds; default: 5555
- headers: extra headers to include in requests the transport makes; default {}
And for TCP:
- type: type name; constant: 'tcp'
- port: port number; default: 10201
- host: hostname; default: '0.0.0.0' (all interfaces)
- timeout: timeout in milliseconds; default: 5555
The client
and listen
methods accept an
options object as the primary way to specify options:
1var seneca = require('seneca') 2seneca() 3 .client({timeout:1000}) 4 .listen({timeout:2000})
As a convenience, you can specify the port and host as optional arguments:
1var seneca = require('seneca') 2seneca() 3 .client( 8080 ) 4 .listen( 9090, 'localhost')
To see the options actually in use at any time, you can call the
seneca.options()
method. Or try
1$ node seneca-script.js --seneca.log=type:options
Releases
- 0.9.0: Fixes from @technicallyjosh; proper glob matching with patrun 5.x
- 0.7.1: fixed log levels
- 0.7.0: all logs now debug level
- 0.2.6: fixed error transmit bug https://github.com/senecajs/seneca/issues/63
Testing with Docker Compose
With docker-machine and docker-compose installed run the following commands:
docker-compose build
docker-compose up
The output will be the stdout from the server and client logs. You should also
see the client instance outputting the result from the server: { hex: '#FF0000' }
Contributing
The Senecajs org encourage open participation. If you feel you can help in any way, be it with documentation, examples, extra testing, or new features please get in touch.
Test
To run tests, simply use npm:
1npm run test
License
Copyright (c) 2013-2016, Richard Rodger and other contributors. Licensed under MIT.
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Info: FSF or OSI recognized license: MIT License: LICENSE:0
Reason
0 existing vulnerabilities detected
Reason
7 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 6
Reason
Found 2/26 approved changesets -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
- Warn: no topLevel permission defined: .github/workflows/build.yml:1
- Warn: no topLevel permission defined: .github/workflows/todo.yml:1
- Info: no jobLevel write permissions found
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/senecajs/seneca-transport/build.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/senecajs/seneca-transport/build.yml/master?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:35: update your workflow using https://app.stepsecurity.io/secureworkflow/senecajs/seneca-transport/build.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/todo.yml:7: update your workflow using https://app.stepsecurity.io/secureworkflow/senecajs/seneca-transport/todo.yml/master?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/todo.yml:9: update your workflow using https://app.stepsecurity.io/secureworkflow/senecajs/seneca-transport/todo.yml/master?enable=pin
- Warn: containerImage not pinned by hash: Dockerfile:1: pin your Docker image by updating node to node@sha256:a569d16e90f2e59da5594793509db37ebfa2d4eb4c5982758fad8f4c79f8ff8f
- Warn: npmCommand not pinned by hash: Dockerfile:11
- Warn: npmCommand not pinned by hash: .github/workflows/build.yml:31
- Info: 0 out of 3 GitHub-owned GitHubAction dependencies pinned
- Info: 0 out of 2 third-party GitHubAction dependencies pinned
- Info: 0 out of 1 containerImage dependencies pinned
- Info: 0 out of 2 npmCommand dependencies pinned
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'master'
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 6 are checked with a SAST tool
Score
4
/10
Last Scanned on 2024-12-16
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn MoreOther packages similar to seneca-transport
seneca-amqp-transport
Official AMQP transport plugin for Seneca
@seneca/sns-transport
Seneca transport for AWS SNS
seneca-transport-test
Standard test cases for Seneca transports.
seneca-zyre-transport
![Seneca](http://senecajs.org/files/assets/seneca-logo.png)<br/> proximity p2p transport plugin using zyre.js