@@ -28,9 +28,8 @@ class SocketIOOutput(OutputChannel):
28
28
def name (cls ) -> Text :
29
29
return "socketio"
30
30
31
- def __init__ (self , sio , sid , bot_message_evt ) -> None :
31
+ def __init__ (self , sio : AsyncServer , bot_message_evt : Text ) -> None :
32
32
self .sio = sio
33
- self .sid = sid
34
33
self .bot_message_evt = bot_message_evt
35
34
36
35
async def _send_message (self , socket_id : Text , response : Any ) -> None :
@@ -44,15 +43,15 @@ async def send_text_message(
44
43
"""Send a message through this channel."""
45
44
46
45
for message_part in text .strip ().split ("\n \n " ):
47
- await self ._send_message (self . sid , {"text" : message_part })
46
+ await self ._send_message (recipient_id , {"text" : message_part })
48
47
49
48
async def send_image_url (
50
49
self , recipient_id : Text , image : Text , ** kwargs : Any
51
50
) -> None :
52
51
"""Sends an image to the output"""
53
52
54
53
message = {"attachment" : {"type" : "image" , "payload" : {"src" : image }}}
55
- await self ._send_message (self . sid , message )
54
+ await self ._send_message (recipient_id , message )
56
55
57
56
async def send_text_with_buttons (
58
57
self ,
@@ -80,7 +79,7 @@ async def send_text_with_buttons(
80
79
)
81
80
82
81
for message in messages :
83
- await self ._send_message (self . sid , message )
82
+ await self ._send_message (recipient_id , message )
84
83
85
84
async def send_elements (
86
85
self , recipient_id : Text , elements : Iterable [Dict [Text , Any ]], ** kwargs : Any
@@ -95,22 +94,22 @@ async def send_elements(
95
94
}
96
95
}
97
96
98
- await self ._send_message (self . sid , message )
97
+ await self ._send_message (recipient_id , message )
99
98
100
99
async def send_custom_json (
101
100
self , recipient_id : Text , json_message : Dict [Text , Any ], ** kwargs : Any
102
101
) -> None :
103
102
"""Sends custom json to the output"""
104
103
105
- json_message .setdefault ("room" , self . sid )
104
+ json_message .setdefault ("room" , recipient_id )
106
105
107
106
await self .sio .emit (self .bot_message_evt , ** json_message )
108
107
109
108
async def send_attachment (
110
109
self , recipient_id : Text , attachment : Dict [Text , Any ], ** kwargs : Any
111
110
) -> None :
112
111
"""Sends an attachment to the user."""
113
- await self ._send_message (self . sid , {"attachment" : attachment })
112
+ await self ._send_message (recipient_id , {"attachment" : attachment })
114
113
115
114
116
115
class SocketIOInput (InputChannel ):
@@ -144,6 +143,19 @@ def __init__(
144
143
self .user_message_evt = user_message_evt
145
144
self .namespace = namespace
146
145
self .socketio_path = socketio_path
146
+ self .sio = None
147
+
148
+ def get_output_channel (self ) -> Optional ["OutputChannel" ]:
149
+ if self .sio is None :
150
+ raise_warning (
151
+ "SocketIO output channel cannot be recreated. "
152
+ "This is expected behavior when using multiple Sanic "
153
+ "workers or multiple Rasa Open Source instances. "
154
+ "Please use a different channel for external events in these "
155
+ "scenarios."
156
+ )
157
+ return
158
+ return SocketIOOutput (self .sio , self .bot_message_evt )
147
159
148
160
def blueprint (
149
161
self , on_new_message : Callable [[UserMessage ], Awaitable [Any ]]
@@ -155,6 +167,9 @@ def blueprint(
155
167
sio , self .socketio_path , "socketio_webhook" , __name__
156
168
)
157
169
170
+ # make sio object static to use in get_output_channel
171
+ self .sio = sio
172
+
158
173
@socketio_webhook .route ("/" , methods = ["GET" ])
159
174
async def health (_ : Request ) -> HTTPResponse :
160
175
return response .json ({"status" : "ok" })
@@ -173,12 +188,14 @@ async def session_request(sid: Text, data: Optional[Dict]):
173
188
data = {}
174
189
if "session_id" not in data or data ["session_id" ] is None :
175
190
data ["session_id" ] = uuid .uuid4 ().hex
191
+ if self .session_persistence :
192
+ sio .enter_room (sid , data ["session_id" ])
176
193
await sio .emit ("session_confirm" , data ["session_id" ], room = sid )
177
194
logger .debug (f"User { sid } connected to socketIO endpoint." )
178
195
179
196
@sio .on (self .user_message_evt , namespace = self .namespace )
180
197
async def handle_message (sid : Text , data : Dict ) -> Any :
181
- output_channel = SocketIOOutput (sio , sid , self .bot_message_evt )
198
+ output_channel = SocketIOOutput (sio , self .bot_message_evt )
182
199
183
200
if self .session_persistence :
184
201
if not data .get ("session_id" ):
0 commit comments