Sockets

Websockets is a protocol which allows bidirectional communications in real time on the Web, a possibility that previously existed only in a simulated and quite expensive way using techniques such as long polling. Opting for this protocol allows you to reduce the header saturation that would occur if HTTP were used instead, especially for applications that require a large volume of communications. In addition, it prevents each application from using a different integration solution, with the compatibility problems that this would entail. On the other hand, it has been seen that its operation is extremely simple: a connection is established, messages are sent / received and the connection is closed. Finally, by operating under the same ports as HTTP, it avoids problems related to firewalls, thus facilitating the operation of products based on service-oriented architectures, among others.

Advantages of using Sockets

  • It is faster than the HTTP protocol.
  • Reduces the use of the network, as it avoids the need to use HTTP packets that contain large amounts of header data, without the need for further processing work.
  • It minimizes the latency in the connections, since it puts less load on the servers, which allows these teams to attend more simultaneous connections.
  • Enables traversing firewalls and proxy servers; if a WebSockets detects the presence of a proxy server, it requests a TCP / IP connection using an HTTP Connect command, after which it can be passed through the proxy without difficulty.
  • It facilitates greater scalability on the web, due to its efficiency when maintaining persistent connections with servers.

Websockets in Ordering API

Ordering API has several features that are usually of continuous use, this would create a tendency to recurrent HTTP requests to certain endpoints, which would cause a server to crash. To avoid this, the Ordering Team implemented the use of web sockets and so instead of making use of HTTP requests, they would have information in real time about things like driver locations, drivers status, orders status changes, and new orders.

¿What can they be used for?

  • Driver location: whit this Developers can implement real-time tracking for drivers.
  • Driver updates: Its use is oriented to see the availability in real time of the drivers.
  • New order: Used to notify is an order was created, this only can be used by Administrator or business owners.
  • Order update: Any change in an order is notified here either changes in status or driver.
  • Order messges

¿How does it work?
Ordering API Sockets currently works with Socket.io in version 4 or another that is compatible with this. To use it, it is necessary to follow a certain flow and also to know its hierarchy to understand how it works.

CONNECTING SOCKET
First of all, the sockets are separated by projects that prevent the information from crossing if two projects share the same space. Because of this, to create, connect the socket and join a room it is required to use the name of the project as shown in the following full use example:

var project = 'demo';
var SocketUrl = 'https://socket-v3.ordering.co/';
var userToken = "eyJ0eXAiOiJKV1QiLC..."
var socket = io(SocketUrl, {
  extraHeaders: {
    Authorization: "Bearer "+ userToken,
  },
  query: "token="+userToken+"&project="+project
});

JOINING THE ROOM
Once the socket is connected it must be joined to the rooms, in Ordering API there are two general rooms one for drivers and another for orders. These rooms are used to organize the flow of information and events, with this it is known that to which users they must respond depending on the actions of Ordering API. To join to rooms, the structure of the parameter is shown in the example project_name + '_orders' for superadmins and project_name +' _ orders_' + user_id, the way in which it joins the room is shown below:

var project = 'demo';
var SocketUrl = 'https://socket-v3.ordering.co/';
var userToken = "eyJ0eXAiOiJKV1QiLC..."
var socket = io(SocketUrl, {
  extraHeaders: {
    Authorization: "Bearer "+ userToken,
  },
  query: "token="+userToken+"&project="+project
});
socket.on('connect', function () {
  var orders_room = project+'_orders_'+user_id; //id is not necesary for superadmins and use '_orders' instead of '_orders_'
  var drivers_room = project+'_drivers';
  socket.emit('join', orders_room);
  socket.emit('join', drivers_room);
}

ROOMS

ROOMDESCRIPTION
project+'_orders_'+user_idThis room is to listen to events for orders as user type business owner and customer, the customer will listen for events related to his orders and business will listen for events related to orders that belong to his business
project+'_ordersThis room is to listen to events for orders as user type Administrator, when an order is made, or when an order changes status.
project+'_drivers'This room is to listen to events for orders as user type Administrator as driver connection or driver location for tracking
project+'_messages_orders' This room is to listen to events for orders messages as administrator
project+'_messages_orders_'+idThis room is to listen to events for orders messages which belong to a user (the user id used)
project+'_messages_orders_'+order_id+'_'+user_levelThis room is to listen to events for orders messages for any user in a specific order

LISTENING TO EVENTS
The next step after joining the room is to listen for the events of the room you joined, the list of events per room are listed below:

EventRoomDescription
'orders_register'ORDERSThis event is when an order is created, the socket only receives if the user is an administrator or business owner, the business owner will only receive if the order is related to any of his business.
'update_order'ORDERSThis event is when anything in an order is changed, its most common use are changes of states of an order.
'drivers_update'DRIVERSThis event is when anything in driver is changed, its most common use is for when a driver connects or disconnects or that is not available.
'tracking_driver'DRIVERSThis event is when a driver sends a location, the use of this event is normally to track the drivers in real time
'message'MESSAGES_ORDERThis event is when a Messages is added in a order this can be a comment, status change or a image.

📘

Order Metafields NEW FEATURE

When a metafield is created in an order and only when it is created it triggers the "update order" event, it does not work when it is updated and only works for the order metafields.

This is an example of how to use events:

var project = 'demo';
var SocketUrl = 'https://socket-v3.ordering.co/';
var userToken = "eyJ0eXAiOiJKV1QiLC..."
var socket = io(SocketUrl, {
  extraHeaders: {
    Authorization: "Bearer "+ userToken,
  },
  query: "token="+userToken+"&project="+project
});
socket.on('connect', function () {
  var orders_room = project+'_orders'+user_id; //id is not necesary for superadmins
  socket.emit('join', orders_room);
  socket.on('orders_register', function (order) {
  	//if there is a new order do something
  });
  socket.on('update_order', function (order) {
  	//if there is a change in an order do something
  });
}

📘

All these events bring with them, data to use when some of them happen. The order update and order register bring all the data of the order, driver update all the data of a diver and tracking driver brings the last location sent by a driver.

Maximun order assigned Per Driver

To optimize the way in which the orders are distributed among drivers, there is a configuration called "autoassign_max_assignments" that when it is not configured by defect is 1 and it works with the socket utility "drivers_update". It says the maximum capacity of orders in progress and pending that a driver can have to post it as busy, Ordering API makes this calculation and returns it in an attribute called "assigned_orders_count"

The configuration can be added through this resource Create Configuration and if there is a list with this Get Configurations and then Edit Configuration with the desired value.

📘

NEW EVENTS

There are new events to get the changes of some models like orders and drivers

EventRoomDescription
'order_change'ORDERSThis event is when anything in an order is changed.
'drivers_changes'DRIVERSThis event is when anything in driver is changed, ('enabled', 'busy', 'available', 'last_available_at', 'schedule')

This is an example of how to use new events:

var project = 'demo';
var SocketUrl = 'https://socket-v3.ordering.co/';
var userToken = "eyJ0eXAiOiJKV1QiLC..."
var socket = io(SocketUrl, {
  extraHeaders: {
    Authorization: "Bearer "+ userToken,
  },
  query: "token="+userToken+"&project="+project
});

socket.on('connect', () => {

  socket.emit('join', {
    project: project,
    room: 'orders',
    user_id: user_id,
    role: 'manager' // manager or customer
  })
  
  socket.on('order_change', (data) => {
    // if there is a change in an order do something
  })
  
  socket.emit('join', {
    project: project,
    room: 'drivers',
    user_id: driver_id,
    role: 'driver'
  })
  
  socket.on('drivers_changes', (data) => {
    // if there is a change in a driver do something
  })
})