mirror of
				https://github.com/avatao-content/baseimage-tutorial-framework
				synced 2025-10-31 14:22:55 +00:00 
			
		
		
		
	Add initial version of WS<->FSM<->ZMQ handler
This commit is contained in:
		
							
								
								
									
										24
									
								
								buttons.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								buttons.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| from transitions import Machine | ||||
|  | ||||
|  | ||||
| class Buttons: | ||||
|     states = ['ayy', 'bee', 'cee'] | ||||
|     transitions = [ | ||||
|         {'trigger': 'anchor_a', 'source': 'ayy', 'dest': 'bee'}, | ||||
|         {'trigger': 'anchor_b', 'source': 'bee', 'dest': 'cee'}, | ||||
|         {'trigger': 'anchor_c', 'source': 'cee', 'dest': 'ayy'}, | ||||
|     ] | ||||
|  | ||||
|     def __init__(self, handler=None): | ||||
|         self.handler = handler | ||||
|         self.machine = Machine(model=self, | ||||
|                                states=Buttons.states, | ||||
|                                transitions=Buttons.transitions, | ||||
|                                initial='ayy', | ||||
|                                send_event=True, | ||||
|                                ignore_invalid_triggers=True, | ||||
|                                after_state_change='forward_message') | ||||
|  | ||||
|     def forward_message(self, event_data): | ||||
|         message = event_data.kwargs.get('message') | ||||
|         self.handler.send_message(message) | ||||
							
								
								
									
										60
									
								
								handlers/zmq_websocket_handler.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								handlers/zmq_websocket_handler.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| import logging | ||||
|  | ||||
| import json | ||||
| from tornado.websocket import WebSocketHandler | ||||
| import zmq | ||||
| from zmq.eventloop.zmqstream import ZMQStream | ||||
| from zmq.eventloop import ioloop | ||||
|  | ||||
| from config import PUBLISHER_PORT, RECEIVER_PORT | ||||
| from buttons import Buttons | ||||
|  | ||||
| ioloop.install() | ||||
|  | ||||
|  | ||||
| class ZMQWebSocketHandler(WebSocketHandler): | ||||
|     def __init__(self, application, request, zmq_context=None, **kwargs): | ||||
|         super().__init__(application, request, **kwargs) | ||||
|         self.zmq_context = zmq_context or zmq.Context.instance() | ||||
|         self.zmq_pull_socket = self.zmq_context.socket(zmq.PULL) | ||||
|         self.zmq_pull_stream = ZMQStream(self.zmq_pull_socket) | ||||
|         self.zmq_pub_socket = self.zmq_context.socket(zmq.PUB) | ||||
|         self.fsm = Buttons(self) | ||||
|  | ||||
|     def open(self, *args, **kwargs): | ||||
|         pub_socket_address = 'tcp://*:{}'.format(PUBLISHER_PORT) | ||||
|         self.zmq_pub_socket.bind(pub_socket_address) | ||||
|         logging.debug('Pub socket bound to {}'.format(pub_socket_address)) | ||||
|         pull_socket_address = 'tcp://*:{}'.format(RECEIVER_PORT) | ||||
|         self.zmq_pull_socket.bind(pull_socket_address) | ||||
|         logging.debug('Pull socket bound to {}'.format(pull_socket_address)) | ||||
|  | ||||
|         def zmq_callback(msg_parts): | ||||
|             anchor, data = msg_parts | ||||
|             logging.debug('Received on pull socket: {}'.format(data.decode())) | ||||
|             self.write_message(data.decode()) | ||||
|  | ||||
|         self.zmq_pull_stream.on_recv(zmq_callback) | ||||
|  | ||||
|     def on_message(self, message): | ||||
|         logging.debug('Received on WebSocket: {}'.format(message)) | ||||
|         self.fsm.trigger(self._parse_anchor(message), message=message) | ||||
|  | ||||
|     def send_message(self, message, anchor: str = None): | ||||
|         if not anchor: | ||||
|             anchor = self._parse_anchor(message) | ||||
|         encoded_message = [part.encode('utf-8') for part in (anchor, message)] | ||||
|         self.zmq_pub_socket.send_multipart(encoded_message) | ||||
|  | ||||
|     def on_close(self): | ||||
|         self.zmq_pull_socket.close() | ||||
|         self.zmq_pub_socket.close() | ||||
|  | ||||
|     # much secure, very cors, wow | ||||
|     def check_origin(self, origin): | ||||
|         return True | ||||
|  | ||||
|     @staticmethod | ||||
|     def _parse_anchor(message): | ||||
|         message_json = json.loads(message) | ||||
|         return message_json['anchor'] | ||||
		Reference in New Issue
	
	Block a user