Невозможно получить StandardWebSocketSession ID программно для тестирования интеграции в Python + Spring - PullRequest
0 голосов
/ 20 января 2020

Я внедряю клиент 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

Вот что я пробовал.

  1. Когда веб-сокет создается, я получаю 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...