voryx / Thruway

PHP Client and Router Library for Autobahn and WAMP (Web Application Messaging Protocol) for Real-Time Application Messaging
MIT License
676 stars 117 forks source link

Issue publishing payload with associative array #344

Open developernaren opened 4 years ago

developernaren commented 4 years ago

I am trying to publish this array which will be consumer as an object

$session->publish('client.1', ['name' => 'Naren']);

I get this error

Screen Shot 2020-06-26 at 12 54 34 PM

I feel like somewhere the code is doing json_encode and json_decode and turning this into an object. dumping the variable $arguements prints it twice once as an array and the second time as an object

Screen Shot 2020-06-26 at 12 58 48 PM

if(is_object($arguments)) {
     $arguments = (array) $arguments;   
}

Adding this condition fixes it but not sure it this has unintended consequences.

I guess the workaround would be to pass array of single json string.

boenrobot commented 2 years ago

In the WAMP spec, the publish message is structured to have a JSON array argument list, and a separate JSON object argument. Thruway expects the 2nd argument to be the array list, and the 3rd one to be the object, which is analogous to how other implementations do it.

To put this another way, your first array needs to be indexed, and the second one needs to be associative. i.e.

$session->publish('client.1', [], ['name' => 'Naren']);

There are several things Thruway could do before making the publish call to make this more convenient, but only one of them is better than the status quo IMO:

  1. Call array_values() on the first array. This would mean your array keys will be lost to the subscriber, and that may not be what you want, and will be tricky to debug if you don't already know about this. Having the exception at least lets you trace the instances where this problem occurs.
  2. Extract all non-index arguments from the first array, and merge them with the second array, preferring the values in the second array in case both arrays define the same keys. That's better, but comes at a significant performance cost, as it needs to be done on every publish call for all members of the first array.
  3. Require SplDoublyLinkedList object instead at the second argument. A SplDoublyLinkedList object can only have integer indexes, and still has arbitrary values, making it a nice fit. However, it currently lacks a convenient way to be created from a normal array, thus making its use here more inconvenient.
  4. Call array_is_list() and throw an exception on the publisher's end (before dispatching the message), rather than throwing it at the subscriber's end. This is the best approach IMO. The only downside is that it requires a polyfill for PHP versions earlier than 8.1.