JSON and stream messaging over HTTP2.
npm install @trevthedev/http2communicator
On the Client
const response = await client.ask({ whatever: 'question or resource request' })
On the Server
server.on('question', async (serverResponse)=>{
serverResponse.reply({ response: 'what ever' })
})
import ServerNode from '@trevthedev/http2communicator'
const server = new ServerNode()
server.on('question', async (serverResponse) => {
console.log(`LOG STEP 1: ${JSON.stringify(serverResponse.json)}`)
// handles any messages sent by client of type 'message' to this serverResponse
serverResponse.on('message', (msg) => console.log(`LOG STEP 4: ${JSON.stringify(msg)}`))
// sends 'hello' JSON message to client's question
serverResponse.say({ first: 'your', name: 'please', step: 2 }, 'hello')
// asks a question of client's question
const question = serverResponse.ask({
do: 'you', like: 'your', name: ['yes', 'no'], step: 3,
})
// handles any messages sent by client of type 'message' to this question
question.on('message', (msg) => {
console.log(`LOG STEP 5: ${JSON.stringify(msg)}`)
question.say({ and: 'I', say: 'more', step: 6 }, 'more')
})
// waits for client to respond to question
console.log(`LOG STEP 7: ${JSON.stringify(await question)}`)
// establishes a new stream from client to comms server (opposite of Push Stream)
// streams can also stream objects - known as Speaker
const incomingStream = await serverResponse.createListener('uploadFile', 'raw')
incomingStream.pipe(process.stdout)
// stream file to client - Push Stream
// streams can also stream objects - known as Speaker
const fileSpeaker = await serverResponse.createSpeaker('downloadFile', 'raw')
fs.createReadStream('package.json').pipe(fileSpeaker)
// after file has been streamed, reply to the original question
fileSpeaker.on('finish', () => serverResponse.reply({ my: 'name', is: 'server' }))
})
server.listen()
import NodeClient from '@trevthedev/http2communicator/client'
const client = new NodeClient()
// ask for something from the comms server (question)
const question = client.ask({ what: 'is', your: 'name', step: 1 })
// handles any messages sent by comms server of type 'hello' to this question
question.on('hello', (msg) => {
console.log(`LOG STEP 2: ${JSON.stringify(msg)}`)
// sends message to comms server of type 'message' to this question
question.say({ i: 'say', stuff: true, step: 4 })
})
// handles any questions from the comms server to this question
// Response object is provided
question.on('question', (response) => {
console.log(`LOG STEP 3: ${JSON.stringify(response.json)}`)
// handles any messages sent by comms server of type 'more' to this response
response.on('more', (msg) => {
console.log(`LOG STEP 6: ${JSON.stringify(msg)}`)
// reply to servers question
response.reply({
answer: 'yes', i: 'like', my: 'name', step: 7,
})
})
// sends message to comms server of type 'message' to this response
response.say({ i: 'also', say: 'stuff', step: 5 })
})
// stream established by comms server.createListener
question.on('uploadFile', (stream) => {
fs.createReadStream('package.json').pipe(stream)
})
// stream established by comms server.createSpeaker
question.on('downloadFile', (stream) => {
stream.pipe(process.stdout)
});
(async () => {
// await response to question
const response = await question
console.log(`LOG STEP 1 ANSWER: ${JSON.stringify(response)}`)
})()
The host of the http2 server.
Instantiation:
import ServerNode from '@TrevTheDev/http2Communicator'
const server = new ServerNode(http2Server, settings)
http2Server
<http2Server> optional http2Server - if one is not provide a new http2SecureServer instance is created based on settings.settings
<object> settings:- serverPort: 8443,
- serverHostName: '127.0.0.1',
- serverPath: '/http2Communicator'
- listenerPath: '/http2Stream'
- keyFile: './dev certificate/selfsigned.key'
- certFile: './dev certificate/selfsigned.crt'
- certArgs: '/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com'
- log: true
starts server listening
port
<number> optional - see settingshostname
<string> optional - see settings serverHostName
- returns <Promise> Promise that gracefully closes all streams
A client the connects to a ServerNode.
Instantiation:
import NodeClient from '@TrevTheDev/http2Communicator/client'
const client = new NodeClient(settings)
settings
<object> settings:- serverAddress: 'https://localhost:8443'
- http2ConnectionOptions: { rejectUnauthorized: false, enablePush: true, }
- serverPath: '/http2Communicator'
- listenerPath: '/http2Stream'
- log: true
Asks a new Question
of the ServerNode
json
<object> question to ask- returns <Question> a
Question
promise that resolves after the response is received
- returns <Promise> Promise that gracefully closes all streams
Extends EventEmitter
Instantiation:
clientNode.ask(Json)
serverResponse.ask(Json)
A Question is a request json
Promise that awaits a response json
. On await
the Question is sent.
- returns <Question> a promise that resolves to the the response json
id
<string> a Unique IdentifierobjectStream
<ObjectStream> ObjectStream used for communicationsjson
<Object> Json of questionresponse
<Response> Response object if anyspeakers
<Object[]> Array of activeSpeakers
response
<Response=> if the Question is related to a particularResponse
- a "sub" question
reply
on receipt this resolves the Question Promise. It will throw if there are any openSpeakers
cancelled
on receipt this rejects the Question Promise withcancelled
message. It will throw if there are any openSpeakers
question
emits aquestion
event with a newResponse
objectlistening
emits aspeakerType
event with aSpeaker
|Stream
object- any messages not of the above type are
emit
ed as their message type
Sends a json object of type via the ObjectStream
. Say will only work after question
has been sent to server
via await
.
Extends Response
Instantiation:
serverNode.on('question', (serverResponse) => {
})
speakers
<Speaker[]> array of connectedSpeakers
|Streams
Listeners
<Speaker[]> array of connected listeningSpeakers
|Streams
Creates a new Speaker
|Stream
that the serverReponse
can send either Objects on or anything else.
speakerName
<string> event that will be emitted on the clientspeakerType
<string='object'> speaker will be aSpeaker
if 'object' or aStream
if 'raw'optional
<boolean=false> if true then no promise is returned, rather returnedSpeaker
will emitspeakerType
event on stream- returns <Promise->Speaker |Speaker > a promise that resolves to a Speaker or a Speaker
Creates a new listening Speaker
|Stream
that the serverReponse
can receive either Objects on or anything else.
speakerName
<string> event that will be emitted on the clientspeakerType
<string='object'> speaker will be aSpeaker
if 'object' or aStream
if 'raw'- returns <Promise->Speaker |Promise->Stream> a promise that resolves to a
Speaker
or aStream
Extends EventEmitter
Instantiation:
question.on('question', (response) => {
})
id
<string> a unique identifierobjectStream
<ObjectStream> ObjectStream used for communicationsjson
<Object> Json of receivedQuestion
questions
<Object[]> Array ofQuestions
asked by thisResponse
awaiting answers
- any messages received are
emit
ed as their message type
Sends json response to this Question
and resolves promise. Type can also be cancelled
to reject the Question
. Throws if any Questions
, Speakers
or Listeners
remain connected.
json
<object> json response to questiontype
<string='reply'>
Only one reply
should be sent.
Asks a new Question
related to this Response
json
<object>question
to ask- returns <Question> a
Question
promise that resolves after the response is received
Sends a json object of type via the ObjectStream
An object stream converts a stream of bytes into a stream of JSON objects. It emits a new event object
for each object received
stream
<stream.Readable|stream.Duplex> stream to become object streameventTarget
<eventTarget> optional target that will emit theobject
,end
,finish
,closed
events
Instantiation via serverResponse.createSpeaker
and serverResponse.createListener
Sends JSON objects in one direction using an ObjectStream
sends json
over ObjectStream
sends json
over ObjectStream
and ends ObjectStream