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

Server Example seems to be broken #269

Closed
Byorun opened this issue Aug 26, 2020 · 5 comments
Closed

Server Example seems to be broken #269

Byorun opened this issue Aug 26, 2020 · 5 comments

Comments

@Byorun
Copy link

Byorun commented Aug 26, 2020

If I try to run the simple-server example my IDE and node (when executed)

image

this error is thrown for

  • readCoils
  • readHoldingRegisters
  • WriteSingleRegister
@Byorun
Copy link
Author

Byorun commented Aug 26, 2020

I put togther a code snippet to test all events (according to modbus-server)

import * as Modbus from "jsmodbus"
import {Server} from 'net'

const netServer = new Server()
const initialHoldingRegisters = Buffer.alloc(10000)
const server = new Modbus.server.TCP(netServer, {
    holding: initialHoldingRegisters
})

server.on('connection', (client) => {
    console.log('connection')
})
server.on('readCoils', (request, cb) => {
    console.log('readCoils')
})
server.on('preReadCoils', (request, cb) => {
    console.log('preReadCoils')
})
server.on('postReadCoils', (request, cb) => {
    console.log('postReadCoils')
})
server.on('readDiscreteInputs', (request, cb) => {
    console.log('readDiscreteInputs')
})
server.on('preReadDiscreteInputs', (request, cb) => {
    console.log('preReadDiscreteInputs')
})
server.on('postReadDiscreteInputs', (request, cb) => {
    console.log('postReadDiscreteInputs')
})
server.on('readHoldingRegisters', (request, cb) => {
    console.log('readHoldingRegisters')
})
server.on('preReadHoldingRegisters', (request, cb) => {
    console.log('preReadHoldingRegisters')
})
server.on('postReadHoldingRegisters', (request, cb) => {
    console.log('postReadHoldingRegisters')
})
server.on('readInputRegisters', (request, cb) => {
    console.log('readInputRegisters')
})
server.on('preReadInputRegisters', (request, cb) => {
    console.log('preReadInputRegisters')
})
server.on('postReadInputRegisters', (request, cb) => {
    console.log('postReadInputRegisters')
})
server.on('writeSingleCoil', (request, cb) => {
    console.log('writeSingleCoil')
})
server.on('preWriteSingleCoil', (request, cb) => {
    console.log('preWriteSingleCoil')
})
server.on('postWriteSingleCoil', (request, cb) => {
    console.log('postWriteSingleCoil')
})
server.on('writeSingleRegister', (request, cb) => {
    console.log('writeSingleRegister')
})
server.on('preWriteSingleRegister', (request, cb) => {
    console.log('preWriteSingleRegister')
})
server.on('postWriteSingleRegister', (request, cb) => {
    console.log('postWriteSingleRegister')
})
server.on('writeMultipleCoils', (request, cb) => {
    console.log('writeMultipleCoils')
})
server.on('preWriteMultipleCoils', (request, cb) => {
    console.log('preWriteMultipleCoils')
})
server.on('writeMultipleCoils', (coils, oldStatus) => {
    console.log('writeMultipleCoils')
})
server.on('postWriteMultipleCoils', (coils, newStatus) => {
    console.log('postWriteMultipleCoils')
})
server.on('postWriteMultipleCoils', (request, cb) => {
    console.log('postWriteMultipleCoils')
})
server.on('writeMultipleRegisters', (request, cb) => {
    console.log('writeMultipleRegisters')
})
server.on('preWriteMultipleRegisters', (request, cb) => {
    console.log('preWriteMultipleRegisters')
})
server.on('writeMultipleRegisters', (holdingRegisters) => {
    console.log('writeMultipleRegisters')
})
server.on('postWriteMultipleRegisters', (holdingRegisters) => {
    console.log('postWriteMultipleRegisters')
})
server.on('postWriteMultipleRegisters', (request, cb) => {
    console.log('postWriteMultipleRegisters')
})


netServer.listen(502)

connection
preReadCoils
postReadCoils
preReadDiscreteInputs
postReadDiscreteInputs
preReadHoldingRegisters
postReadHoldingRegisters
preReadInputRegisters
postReadInputRegisters
preWriteSingleCoil
postWriteSingleCoil
preWriteSingleRegister
postWriteSingleRegister
preWriteMultipleRegisters
writeMultipleRegisters
writeMultipleRegisters
postWriteMultipleRegisters
postWriteMultipleRegisters
postWriteMultipleRegisters
postWriteMultipleRegisters
preWriteMultipleCoils
writeMultipleCoils
writeMultipleCoils
postWriteMultipleCoils
postWriteMultipleCoils
postWriteMultipleCoils
postWriteMultipleCoils

  • For reading only pre and post events are fired
  • For writing the main events from WriteSingleCoil and WriteSingleRegister are missing

In addition it is not clear (for me at least) how I should use the BufferCB while handling the event

@alexbuczynsky
Copy link
Collaborator

This seems to be a bug caused by the on(event) overload for the "connection" event:

public on (event: 'connection', listener: (client: ModbusServerClient<any, any, any>) => void): this

public on (event: 'connection', listener: (socket: Socket) => void): this

The type overload needs to be investigated. I will do that and report back here

@alexbuczynsky
Copy link
Collaborator

In addition it is not clear (for me at least) how I should use the BufferCB while handling the event
From my understanding, the callback can be optionally called to send a response back to the client for that request. You can use this as an interceptor to prevent users from writing invalid data to specific portions of the buffer for example.

It is used by the ModbusServerClient to send the payload from a read / write request back to the socket:

this._responseHandler.handle(request, (response) => {
this._socket.write(response, () => {
debug('response flushed', response)
})
})

@stefanpoeter could maybe provide more insight.

@stefanpoeter
Copy link
Member

Well that makes no sense to me either.

In addition it is not clear (for me at least) how I should use the BufferCB while handling the event
From my understanding, the callback can be optionally called to send a response back to the client for that request. You can use this as an interceptor to prevent users from writing invalid data to specific portions of the buffer for example.

The main Idea is that you can react to the request but cannot alter them. The ability to alter the response is probably a good addition. For example one should be able to throw an exception in the listener and therefor changing the response. The buffer in the callback and the callback itself makes no sense, don't know how this got there :-). I think that was an attempt to async the request but went totally wrong.

This might be a possible extension for the listener


private _handleReadCoil (request: ModbusAbstractRequest, cb: (buffer: Buffer) => void) {

 ...

try {
this._server.emit('preReadCoils', request)
} catch (e) {
 //send alternative payload with an error response body.
 return;
}

 const responseBody = ReadCoilsResponseBody.fromRequest(request.body, this._server.coils)
 const response = this._fromRequest(request, responseBody)
 const payload = response.createPayload()
 cb(payload)

 // throwing an exception does not make sense here since the resonse has already been issued
 this._server.emit('postReadCoils', request)

}


For writing the main events from WriteSingleCoil and WriteSingleRegister are missing

Should be fixed easily.

@stif
Copy link

stif commented Sep 21, 2020

I also experienced this bug (only pre and post events fired):

preReadDiscreteInputs
postReadDiscreteInputs

unfortunately it is not clear to me how to fix it, so i will move on an try another module..

@robot2045
Copy link

I'm also experiencing this problem, any solution ? @alexbuczynsky @stefanpoeter
server.on('readCoils', function (request, response, send) is never reached

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

Successfully merging a pull request may close this issue.

5 participants