Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TCP / RTU Client Manager #255

Open
wants to merge 19 commits into
base: v4.0-dev
Choose a base branch
from
Open

TCP / RTU Client Manager #255

wants to merge 19 commits into from

Conversation

alexbuczynsky
Copy link
Collaborator

@alexbuczynsky alexbuczynsky commented Feb 4, 2020

Summary

Every time I use jsmodbus in one of my projects, I wind up creating a utility class to manage all the clients. I also like to make sure that only one socket is being used for a single host:port combination at a time like the image below show:
ModbusManagerSocketClientLayout

This pull request adds two main new classes:

  1. ModbusTCPClientManager
  2. ModbusRTUClientManager

Description

The class manages the active socket connections and only allows one socket connection open to any modbus master at a time. Each client then uses the same socket reference if the client matches the host and port number of that already created socket.

For example, for the ModbusTCPClientManager it keeps a record of the host and port that each client being added to the system has and assigns the correct currently active socket connection to the clients as they are added. The image below shows a diagram of how this works.

image

Below is an example use case for why this manager can be very useful:

const modbus = require('jsmodbus')

const manager = new modbus.ModbusTCPClientManager()

const socket = manager.findOrCreateSocket({
  host: 'localhost',
  port: 5052,
})

for(let i = 0; i < 50; i++) {
  manager.findOrCreateClient({
    host: 'localhost',
    port: 5052,
    slaveId: i
  })
}


console.log(manager.clientCount) // should be 50
console.log(manager.socketCount) // should be 1


socket.on('connect', () => {
  console.log('SOCKET CONNECTED')

  setInterval(() => {
    for(const [clientId, client] of manager.clients){
      client
        .readCoils(0, 5)
        .then(({response}) => console.log(response.body.valuesAsArray))
        .catch(console.error)
    }
  }, 1000)
})

Notes:

BLOCKED WHILE WAITING FOR #254
The version should be bumped to 4.1 since this is a new feature

@stefanpoeter
Copy link
Member

Hey @alexbuczynsky

this is indeed a useful feature, thanks for your work. I will check your code in the next days and write some feedback if necessary.

@stefanpoeter
Copy link
Member

Hey @alexbuczynsky,

common things I noticed that I could not annotate in your code. First the standard linter is missing in the package.json for the js files. There are a lot of complaints about assert.equals is deprecated, wrong indentation etc. Please change the following in the package.json

"lint": "tslint -c tslint.json 'src/**/*.ts' **&& standard**",

Some Tests are marked with ToDo, what is it about that?

assert.equal(manager.socketCount, 1, 'Number of sockets should be one')
})

it('should find a created client', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test Case for when a client is not found?

slaveId
},defaultSerialPortOptions))

assert.throws(() => manager.createClient({ host, port, slaveId }))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

host and port are undefined

@stefanpoeter
Copy link
Member

Is it a common use case to add or remove clients during runtime? Have you checked the memory behaviour in that case?

@alexbuczynsky
Copy link
Collaborator Author

alexbuczynsky commented Mar 4, 2020

@stefanpoeter sorry I have been extremely busy with work. Will get back to this as soon as I can. A couple of comments for now...

Linting
We will have to move the linting to a new PR. Typescript tslint has been deprecated in favor of regular eslint. There is an easy way to setup your project via the cli to do the linting of your typescript code with support out of the box for standardjs style guide.

Missing test cases
completely forgot to add those. will go back and do that

Memory Behavior

Is it a common use case to add or remove clients during runtime? Have you checked the memory behaviour in that case?

I used the same client manager class for a work based project. The server has been running for the past 3 months without any noticeable memory issues. If we want data to back up that statement, I would have to run some stress test to check this.

@stefanpoeter
Copy link
Member

Hi @alexbuczynsky no need to be sorry. This is a open source project so you do what you do when you do it :-)

Some data to check the memory behaviour would be great :-)

@arobal
Copy link

arobal commented Dec 23, 2021

Hi,

I just tried to build the changes on Ubuntu, but it fails building some dependencies of the serialport package (see logs).

2021-12-23T10_27_10_780Z-debug.log

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants