STOMP Websocket ด้วย stomp-js + sockjs

STOMP ย่อมาจาก Simple (or Streaming) Text Orientated Messaging Protocol ใช้สื่อสารส่งข้อมูลกัน ต้อง implement ทั้ง STOMP SERVER และ STOMP Client

โดยปกติแล้วการสร้าง STOMP Client จะใช้ Web Socket class ในการเชื่อมต่อด้วย Web Socket Protocol ws:// ดังตัวอย่าง

var url = "ws://localhost:port/entryURI";
var client = Stomp.client(url);

แต่ในบาง Web Browser ไม่ support Web Socket protocol ws:// แล้ว จึงต้องใช้ SockJS มาช่วยแก้ปัญหานี้ และถือเป็นข้อดีของมัน โดยจะใช้ URL แทน ws://

var ws = new SockJS(url);
var client = Stomp.over(ws);

ตัวอย่าง STOMP Client

1. โหลด js ของ stompjs กับ sockjs โดยใช้ CDN url ควรตรวจสอบ latest version

<script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>

2. ต่อ websocket connection และดักฟัง subscribe channel โดยในตัวอย่างนี้ url ในการเชื่อมต่อ คือ http://localhost:port/socket

var ws = new SockJS(url);
var client = Stomp.over(ws);
    client.connect({}, function(frame) {
      var userid= Math.floor((Math.random() * 100) + 1);
      client.subscribe("/channel"+userid, (message) => {
        if(message.body) {
          console.log(message.body);
        }
    });
 });

3. ส่งข้อมูล (send) ไปหา websocket server

client.send("/app/send/message", {}, qrcode);

ตัวอย่าง STOMP Server ด้วย Spring Boot

1.เพิ่ม spring-boot-starter-websocket dependency ที่ pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

2.สร้างไฟล์ WebSocketConfiguration โดย URL ในการเชื่อมต่อจาก Stomp Client ของ Web Socket ในตัวอย่างจะเป็น http://localhost:port/socket และเปิดช่องการสื่อสาร 2 ช่อง คือ global-channel สำหรับสื่อสารถึงทุกคน และ channel สำหรับสื่อสาร 1-1

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration extends AbstractWebSocketMessageBrokerConfigurer {
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/socket")
                .setAllowedOrigins("*")
                .withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.setApplicationDestinationPrefixes("/app") //prefix channel
                .enableSimpleBroker("/global-channel");//The “/global-channel” channel defining;
                .enableSimpleBroker("/channel");//The “/channel” channel defining;
    }
}

3.สร้าง RestController เทสการส่งข้อมูลผ่าน Web Socket โดย @MessageMapping จะทำงานเมื่อ Stomp Client มีการส่งข้อมูลผ่าน javascript object ด้วย method send โดยจะส่งข้อมูล broadcast ออกไปให้ global-channel ส่วน @RequestMapping จะเป็น Rest เรียกมาจาก URL method GET จะทำการส่งข้อมูล broadcast 1 ต่อ 1 ไปให้ userid ที่ส่งเข้ามา

@RestController
public class WebSocketController {

    private final SimpMessagingTemplate template;

    @Autowired
    WebSocketController(SimpMessagingTemplate template){
        this.template = template;
    }

    //The same as @RequestMapping for RestController we need to use @MessageMapping for websockets.
    @MessageMapping("/send/message")
    public void onReceivedMessage(String message){
        this.template.convertAndSend("/global-channel",new SimpleDateFormat("HH:mm:ss").format(new Date())+"- "+message);
    }

    @RequestMapping(value = "/rest/send/message",  method = { RequestMethod.GET})
    public @ResponseBody
    String testsend( @RequestParam Map<String,String> allRequestParams,HttpServletRequest httpRequest) throws Exception {
     
        String userid= allRequestParams.get("userid");
        this.template.convertAndSend("/channel/"+userid, "send message " + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "<br>");
        return "OK";
    }

}

Related posts:

This entry was posted in java, knowledge, spring boot, websocket. Bookmark the permalink.