Я внедряю клиент Stomp в Python, чтобы я мог автоматизировать интеграционное тестирование. Я не хочу использовать браузер или javascript для тестирования. Также использование Sock JS также не будет работать, так как мне не удалось найти клиентскую библиотеку Sock JS для него в Python
. В весеннем загрузочном коде я проделал следующее для тестирования
Файл: WebSocketConfig. java
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic", "/user");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
// registry.addEndpoint("/gs-guide-websocket").withSockJS();
registry.addEndpoint("/gs-guide-websocket").setAllowedOrigins("*").addInterceptors(new HttpHandshakeInterceptor());
}
}
Файл GreetingController. java
@Controller
public class GreetingController {
@Autowired
SimpMessagingTemplate template;
@MessageMapping("/stats")
@SendToUser("/queue/position-updates")
public void SendJobStats(SimpMessageHeaderAccessor headers) throws Exception {
System.out.println("Headers are " + headers);
try {
for (int i = 0; i < 300; i++) {
Thread.sleep(1000);
String json = String.format(
"{ \"content\" : \"This is a message specific to a user %d \" }",
i);
System.out.println("JSON IS " + json);
template.setMessageConverter(new MappingJackson2MessageConverter());
template.convertAndSendToUser(headers.getSessionId(),
"/queue/position-updates",
json,
headers.getMessageHeaders());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
В коде python я сделал
import random
import stomper as stomper
import websocket
import json
import ssl
import pprint
def main():
websocket.enableTrace(True)
# Connecting to websocket
# ws = websocket.create_connection("ws://localhost:8080/gs-guide-websocket",
# sslopt={
# "cert_reqs": ssl.CERT_NONE,
# "check_hostname": False,
# "ssl_version": ssl.PROTOCOL_TLSv1
# })
# ws = websocket.create_connection("ws://localhost:8080")
# ws = websocket.create_connection("ws://localhost:9001/gs-guide-websocket")
ws = websocket.create_connection("ws://localhost:8080/gs-guide-websocket")
print("WebSocket is ", ws)
print("WebSocket DIR", ws)
print(ws)
pprint.pprint(ws)
import pdb
pdb.set_trace()
"ws://193.88.52.52:8080/gs-guide-websocket")
ws.send(msg)
# Subscribing to topic
userid = input("Give me the user session id : ")
subEndPoint = "/user/" + str(userid) + "/queue/position-updates"
sub = stomper.subscribe(subEndPoint, "", ack='client')
print("Subscribe message is ", sub)
ws.send(sub)
msg = stomper.Frame()
msg.cmd = "SEND"
msg.headers = {
'destination': '/app/stats',
'content-type': 'application/json'
}
msg.body = "test"
x = msg.pack()
print("Sending Data", x)
ws.send(x)
while True:
print("Receiving data: ")
d = ws.recv()
print(d)
Когда код python запрашивает идентификатор сеанса пользователя - я копирую следующее 3c71dd82-353b-cb82-94c3-d8e0f6378e18 (это отличается для каждого веб-сокета) из журналов работающего сервера Tomcat , а затем код python правильно получает сообщение.
..], byteCount=39, last=true], StandardWebSocketSession[id=3c71dd82-353b-cb82-94c3-d8e0f6378e18, uri=ws://localhost:8080/gs-guide-websocket]
2020-01-21 00:43:20.619 TRACE 6238 --- [nio-8080-exec-5] s.w.s.h.LoggingWebSocketHandlerDecorator : Handling TextMessage payload=[SUBSCRIBE
..], byteCount=106, last=true] in StandardWebSocketSession[id=3c71dd82-353b-cb82-94c3-d8e0f6378e18, uri=ws://localhost:8080/gs-guide-websocket]
2020-01-21 00:43:20.619 TRACE 6238 --- [nio-8080-exec-5] o.s.messaging.simp.stomp.StompDecoder : Decoded SUBSCRIBE {id=[], destination=[/user/3c71dd82-353b-cb82-94c3-d8e0f6378e18/queue/position-updates], ack=[client]} session=null
2020-01-21 00:43:20.619 TRACE 6238 --- [nio-8080-exec-5] o.s.messaging.simp.stomp.StompDecoder : Decoded heart-beat
2020-01-21 00:43:20.619 TRACE 6238 --- [nio-8080-exec-5] o.s.w.s.m.StompSubProtocolHandler : From client: SUBSCRIBE /user/3c71dd82-353b-cb82-94c3-d8e0f6378e18/queue/position-updates id= session=3c71dd82-353b-cb82-94c3-d8e0f6378e18
Я не могу получить указанный идентификатор сессии c программно и мне нужна помощь для него. Вывод
Python
> $ ./test.py
--- request header ---
GET /gs-guide-websocket HTTP/1.1
Upgrade: websocket
Host: localhost:8080
Origin: http://localhost:8080
Sec-WebSocket-Key: V3dtGAPyymZK54AvDtFS3w==
Sec-WebSocket-Version: 13
Connection: upgrade
-----------------------
--- response header ---
HTTP/1.1 101
Set-Cookie: JSESSIONID=46D962E44064276D17C886C54F377F53; Path=/; HttpOnly
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Accept: z8i0yfes/4402uP+ecyiI+EaTmw=
session-id: 46D962E44064276D17C886C54F377F53
Date: Mon, 20 Jan 2020 19:13:07 GMT
-----------------------
WebSocket is <websocket._core.WebSocket object at 0x7fb610caeac8>
WebSocket DIR <websocket._core.WebSocket object at 0x7fb610caeac8>
<websocket._core.WebSocket object at 0x7fb610caeac8>
<websocket._core.WebSocket object at 0x7fb610caeac8>
> /home/rishi/test.py(36)main()
-> msg = stomper.connect('bob', '1234',
(Pdb) c
send: b'\x81\xf4\xfe\x85\x90\xcd\xbd\xca\xde\x83\xbb\xc6\xc4\xc7\x9f\xe6\xf3\xa8\x8e\xf1\xbd\xbb\x9b\xf7\xe3\xa4\x91\xeb\xaa\xfc\xd0\xb4\x9a\xa5\x91\xf6\xe4\xf7\x89\xf6\xaa\xe2\xd1\xb4\xa9\xfe\xd0\xbd\xa8\xe3\xcb\xb7\xbe\xf8\xcc\xbf\xa8\xfd\xc6\xb5\xbf\xaa\x8d\xa8\xf7\xb8\x97\xe1\xf5\xe0\x89\xe0\xf2\xbe\x91\xe6\xfb\xa8\x8a\x8f\xf8\xa8\x9f\xf7\xe4\xe0\x9c\xe0\xf1\xb9\xc4\xb5\xbc\xfd\xf4\xe9\xff\xaa\x97\xeb\xaa\xaf\x91\xe7\x9a\xbd\x9f\xf6\xe3\xae\x91\xe1\xf5\xf7\xcf\xb7\xa3\xf9\xf4\x8f\x90\xc7'
Give me the user session id : 3c71dd82-353b-cb82-94c3-d8e0f6378e18
Subscribe message is SUBSCRIBE
id:
destination:/user/3c71dd82-353b-cb82-94c3-d8e0f6378e18/queue/position-updates
ack:client
send: b'\x81\xea-\x8b\xedz~\xde\xaf)n\xd9\xa48h\x81\x84\x1e\x17\x81\x89\x1f^\xff\x84\x14L\xff\x84\x15C\xb1\xc2\x0f^\xee\x9fU\x1e\xe8\xdaKI\xef\xd5H\x00\xb8\xd8IO\xa6\x8e\x18\x15\xb9\xc0C\x19\xe8\xdeWI\xb3\x88JK\xbd\xdeM\x15\xee\xdcB\x02\xfa\x98\x1fX\xee\xc2\nB\xf8\x84\x0eD\xe4\x83WX\xfb\x89\x1bY\xee\x9epL\xe8\x86@N\xe7\x84\x1fC\xff\xe7p-\x81'
Sending Data SEND
content-type:application/json
destination:/app/stats
test
send: b'\x81\xc1\x13L\xb6\xc7@\t\xf8\x83\x19/\xd9\xa9g)\xd8\xb3>8\xcf\xb7vv\xd7\xb7c \xdf\xa4r8\xdf\xa8}c\xdc\xb4|"\xbc\xa3v?\xc2\xae}-\xc2\xae|"\x8c\xe8r<\xc6\xe8`8\xd7\xb3`F\xbc\xb3v?\xc2\xc7\x19'
Receiving data:
CONNECTED
version:1.1
heart-beat:0,0
Receiving data:
MESSAGE
content-type:application/json
destination:/user/3c71dd82-353b-cb82-94c3-d8e0f6378e18/queue/position-updates
subscription:
message-id:3c71dd82-353b-cb82-94c3-d8e0f6378e18-0
content-length:63
"{ \"content\" : \"This is a message specific to a user 0 \" }"
Receiving data:
MESSAGE
content-type:application/json
destination:/user/3c71dd82-353b-cb82-94c3-d8e0f6378e18/queue/position-updates
subscription:
message-id:3c71dd82-353b-cb82-94c3-d8e0f6378e18-1
content-length:63
"{ \"content\" : \"This is a message specific to a user 1 \" }"
Receiving data:
MESSAGE
content-type:application/json
destination:/user/3c71dd82-353b-cb82-94c3-d8e0f6378e18/queue/position-updates
subscription:
message-id:3c71dd82-353b-cb82-94c3-d8e0f6378e18-2
content-length:63
Вот что я пробовал.
- Когда веб-сокет создается, я получаю JSESSIONID, который не совпадает с идентификатором сеанса выше.
200~HTTP/1.1 101
Set-Cookie: JSESSIONID=5E4698B4282C17C2988006179FD519BB; Path=/; HttpOnly
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Accept: 26MVFRKslIJZFb2VASLnzYoYDRE=
Date: Mon, 20 Jan 2020 18:53:52 GMT
Когда я использую JavaScript и Sock JS, я легко могу получить сессию, извлекая ее из
transport.url , как показано ниже. Но я не смог сделать это в NodeJS, так как я незнаком с ним, и мне нужен был код в Python
function connect() {
var socket = new SockJS('/gs-guide-websocket');
var socket = Stomp.client('/gs-guide-websocket');
stompClient = Stomp.over(socket);
stompClient.connect("rishi", "rishi", function (frame) {
var url = stompClient.ws._transport.url;
url = url.replace( "ws://localhost:8080/gs-guide-websocket", "");
console.log("Replaced URL Your current session is: " + url);
url = url.replace("/websocket", "");
console.log("Replaced WebSocket Your current session is: " + url);
url = url.replace(/[0-9]+/, "");
console.log("Replaced user number Your current session is: " + url);
url = url.replace("/", "");
console.log("Replaced slashes " + url);
url = url.replace("/", "");
console.log("Replaced slashes " + url);
sessionId = url;
setConnected(true);
console.log('Connected: ' + frame);
var subscribeEndPoint = "/user/" + sessionId + "/queue/position-updates";
console.log("Subscribe EndPint is ", subscribeEndPoint);
stompClient.subscribe(subscribeEndPoint, function (greeting) {
showGreeting(JSON.parse(greeting.body).content);
});
}); }
Я попытался прочитать документацию SpringBoot и WebSockets, но не смог найти способ обойти это.
ОБНОВЛЕНИЕ:
Одна проблема, которую я обнаружил, что при подключении к WebSocket в STOMP ответ не имеет идентификатора сеанса
CONNECTED
version:1.1
heart-beat:0,0
Я использовал после подключения к веб-сокету с сообщением Stomp
msg = stomper.connect('bob', '1234',
"ws://193.88.52.52:8080/gs-guide-websocket")
ws.send(msg)
print("Message is \n", msg)
Это имеет место, даже если я использую WebSocket + Stomp в JS.