SpringWebSocket etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
SpringWebSocket etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

7 Mart 2023 Salı

SpringWebSocket WebSocketHandler Arayüzü

Giriş
Şu satırı dahil ederiz
import org.springframework.web.reactive.socket.WebSocketHandler;
Örnek
Şöyle yaparız
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.socket.WebSocketHandler;
import org.springframework.web.reactive.socket.WebSocketMessage;
import org.springframework.web.reactive.socket.WebSocketSession;
import reactor.core.publisher.Mono;

import java.util.List;

@Component
public class ReactiveServerWebSocketHandler implements WebSocketHandler {

    @Override
    public @NotNull
    Mono<Void> handle(@NotNull WebSocketSession session) {
        return session.send(session.receive()
                .map(WebSocketMessage::getPayloadAsText)
                .map(session::textMessage)
        );
    }

    @Override
    public @NotNull
    List<String> getSubProtocols() {
        return WebSocketHandler.super.getSubProtocols();
    }
}

21 Ocak 2021 Perşembe

SpringWebSocket WebSocketConnectionManager Sınıfı

Giriş
Şu satırı dahil ederiz
import org.springframework.web.socket.client.WebSocketConnectionManager;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
import org.springframework.web.socket.handler.TextWebSocketHandler;
constructor
Şöyle yaparız
public class MyTextWebSocketHandler extends TextWebSocketHandler {...}

String wsUrl = ...;
//A WebSocket connection manager that is given a URI, a WebSocketClient, and a
//WebSocketHandler, connects to a WebSocket server through start() and stop() methods. 
//If setAutoStartup(boolean) is set to true this will be done automatically when the Spring
//ApplicationContext is refreshed.
WebSocketConnectionManager connectionManager = 
  new WebSocketConnectionManager(new StandardWebSocketClient(),
                                 new MyTextWebSocketHandler(), 
                                 wsUrl);
connectionManager.start();

13 Ocak 2021 Çarşamba

SpringWebSocket STOMP Broker Kullanımı

Giriş
SpringBoot, basit bir STOMP Broker olarak işlev görebilir. Açıklaması şöyle
When using Spring’s STOMP support, the Spring WebSocket application acts as the STOMP broker to clients. Messages are routed to @Controller message-handling methods or to a simple, in-memory broker that keeps track of subscriptions and broadcasts messages to subscribed users. You can also configure Spring to work with a dedicated STOMP broker (e.g. RabbitMQ, ActiveMQ, etc) for the actual broadcasting of messages. In that case Spring maintains TCP connections to the broker, relays messages to it, and also passes messages from it down to connected WebSocket clients. Thus Spring web applications can rely on unified HTTP-based security, common validation, and a familiar programming model message-handling work.
1. In-Memory Broker Başlatılır
WebSocketMessageBrokerConfigurer arayüzünden kalıtan bir sınıf kodlanır ve bu sınıfa @Configuration + @EnableWebSocketMessageBroker anotasyonları eklenir

Bu sınıf STOMP istemcisinin bağlanacağı adresi ve kuyruk isimlerini belirtir.

2. STOMP Mesajları Gönderme
STOMP mesajları göndermek için SimpMessagingTemplate kullanılır. Belirtilen kuyruğa mesaj gönderilir. Kuyruk "/topic" şeklinde başlıyorsa, bu kuyruğu dinleyen tüm abonelere gönderilir.

3. STOMP Mesajları Alma
Eğer bir istemci tarafından gönderilen mesajları almak istiyorsak @MessageMapping anotasyonu ile işaretli bir metod yazmak gerekir. Bu mesajı diğer abonelere de yaymak istersek ilave olarak @SendTo anotasyonu ile hangi "topic" veya "queue" ya yönlendirileceğini de belirtebiliriz.

4. İstemci Tarafı
SockJS kullanarak İstemic tarafı kodlanır

Örnek
SimpMessagingTemplate sınıfının convertAndSend() metodu belirtilen topic'i dinleyen herkese mesajı gönderir. Mesaj JSON olarak gönderilir. Mesajın JSON olarak gönderilmesinin sebebi sanırım @EnableWebSocketMessageBroker anotasyonunun kullanılması
@Component
public class RabbitMQListener {
  @Autowired
  private SimpMessagingTemplate messagingTemplate;

  @RabbitListener(queues = "${spring.rabbitmq.queueName}")
  public void receive(Foo message){
    messagingTemplate.convertAndSend("/topic.socket.rabbit", message);
  }
}



22 Aralık 2020 Salı

SpringWebSocket Kullanımı

Giriş
SpringBoot, WebSocket kullanımında sunucu veya istemci olabilir

Maven
Şu satırı dahil ederiz
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Sunucu
Bu kullanımı açıklayan bir yazı burada.
1. WebSocketConfigurer sınıfından kalıtan bir sınıfı kodla. Bu sınıf handler olarak bir WebSocketHandler nesnesi gerektirir.
2. Gelen mesajları işlemek veya mesaj göndermek için TextWebSocketHandler veya BinaryWebSocketHandler veya WebSocketHandler kodla

İstemci
1. Bir tane WebSocketConnectionManager gerekir.
2. Bu sınıfa bir tane WebSocketClient takılır. Bu StandardWebSocketClient veya SockJsClient olabilir.
Ayrıca mesajları işleyen bir WebSocketHandler takılır.

Açıklaması şöyle
Receiving Text and Binary Data
WebSocket communication consists of messages and application code and does not need to worry about buffering, parsing, and reconstructing received data. For example, if the server sends a 1 MB payload, the application’s onmessage callback will be called only when the entire message is available on the client.

Further, the WebSocket protocol makes no assumptions and places no constraints on the application payload: both text and binary data are fair game. Internally, the protocol tracks only two pieces of information about the message: the length of payload as a variable-length field and the type of payload to distinguish UTF-8 from binary transfers.



12 Kasım 2020 Perşembe

SpringWebSocket WebSocket, Stomp, SockJS İlişkisi

Giriş
Bu üçlünün ilişkisi şöyle. Bu üçlünün ayarlandığı AbstractWebSocketMessageBrokerConfigurer sınıfı yazısına bakabilirsiniz.

WebSocket  - Transport
WebSocket TCP değildir ancak TCP gibi düşünülebilir. İstemciden sunucuya çift yönlü bir socket bağlantısı açar. Açıklaması şöyle
The WebSocket API enables web applications to handle bidirectional communications with server-side process in a straightforward way. Developers have been using XMLHttpRequest ("XHR") for such purposes, but XHR makes developing web applications that communicate back and forth to the server unnecessarily complex. XHR is basically asynchronous HTTP, and because you need to use a tricky technique like long-hanging GET for sending data from the server to the browser, simple tasks rapidly become complex. As opposed to XMLHttpRequest, WebSockets provide a real bidirectional communication channel in your browser. Once you get a WebSocket connection, you can send data from browser to server by calling a send() method, and receive data from server to browser by an onmessage event handler.

In addition to the new WebSocket API, there is also a new protocol (the "WebSocket Protocol") that the browser uses to communicate with servers. The protocol is not raw TCP because it needs to provide the browser's "same-origin" security model. It's also not HTTP because WebSocket traffic differers from HTTP's request-response model. WebSocket communications using the new WebSocket protocol should use less bandwidth because, unlike a series of XHRs and hanging GETs, no headers are exchanged once the single connection has been established. To use this new API and protocol and take advantage of the simpler programming model and more efficient network traffic, you do need a new server implementation to communicate with.
Stomp - Payload
Stomp bir  metin (text) protokolü. Transport protokolü olarak WebSocket kullanmak zorunda değil. Stomp mesajı (frame) şu 3 alandan oluşur
command ("CONNECT", "SEND", etc.)
headers JavaScript object
body
SockJS - Transport İçin B Planı Sağlar
Direkt WebSocket kullanmak yerine SockJS kullanılırsa, WebSocket'in mevcut olmadığı durumlarda da iletişim sağlanabilir. Açıklaması şöyle
Under the hood SockJS tries to use native WebSockets first. If that fails it can use a variety of browser-specific transport protocols and presents them through WebSocket-like abstractions.

SockJS is intended to work for all modern browsers and in environments which don't support the WebSocket protocol -- for example, behind restrictive corporate proxies.
Farklı protokoller şunlar olabilir
xhr-streaming, xhr-polling, and so on












11 Kasım 2020 Çarşamba

SpringWebSocket SimpMessagingTemplate Sınıfı

Giriş
convertAndSendToUser() metodu ile belirli bir kullanıcıya mesaj gönderir.
convertAndSend metodu ile tüm kullanıcılara mesaj gönderir.

17 Ağustos 2020 Pazartesi

SpringWebSocket WebSocketConfigurer Arayüzü

Giriş
WebSocket çift yönlüdür. Aynı TCP bağlantısı gibidir. Açıklaması şöyle
WebSocket establishes a connection using a handshake request, after which the communication becomes bidirectional where there is no concept of response to a request.
Bağlantı bir kere kurulduktan sonra artık maliyeti yok gibidir. Açıklaması şöyle.
The crucial distinction between WebSockets and typical REST-based APIs is that clients based on the former protocol always establish long-running TCP connections and, once connected, the overhead they incur is practically negligible.
WebSockets streaming için tek yöntem değil. Açıklaması şöyle
Websockets, SSE (Server-sent Events) or XHR streaming are all good protocol choices for streaming updates in a browser.
Diğer 
Bu sınıfı kullanmak istemiyorsak şöyle yaparız. Burada direkt bir HandlerMapping  yani SimpleUrlHandlerMapping yaratılıyor.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.HandlerMapping;
import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping;
import org.springframework.web.reactive.socket.WebSocketHandler;

@Configuration
public class ReactiveServerWebSocketConfig {
  @Autowired
  private WebSocketHandler webSocketHandler;

  @Bean
  public HandlerMapping webSocketHandlerMapping() {
    Map<String, WebSocketHandler> map = new HashMap<>();
    map.put("/webflux", webSocketHandler);

    SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
    handlerMapping.setOrder(-1);
    handlerMapping.setUrlMap(map);
    return handlerMapping;
  }
}

registerWebSocketHandlers metodu
Handler TextWebSocketHandler'dan kalıtan bir sınıf olabilir.
Handler AbstractWebSocketHandler'dan kalıtan bir sınıf olabilir.

Örnek
Şöyle yaparız
public class WebSocketConfiguration implements WebSocketConfigurer {
  
  @Override
  public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    registry.addHandler(new WebSocketHandler(), "/presentation").setAllowedOrigins("*");
  }
}
Örnek - Interceptor
Şöyle yaparız.
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

  @Override
  public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    registry.addHandler(myWebSocketController(), "/chat")
      .addInterceptors(new HttpSessionHandshakeInterceptor())
      .setAllowedOrigins("*");
  }

  @Bean
  public MyWebSocketController myWebSocketController() {
    return new MyWebSocketController();
  }
}
Örnek - SockJS
Şöyle yaparız.
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer
{
  @Override
  public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    registry.addHandler(myHandler(), "/websocket").withSockJS();
  }

  @Bean
  public ServerHandler myHandler() {
    return new ServerHandler();
  }
}

12 Temmuz 2018 Perşembe

SpringWebSocket StompWebSocketEndpointRegistration Arayüzü

addInterceptors metodu
Elimizde şöyle bir kod olsun
public class WSHandshakeInterceptor implements HandshakeInterceptor {
  @Override
  public boolean beforeHandshake(ServerHttpRequest serverHttpRequest,
   ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler,
   Map<String, Object> map) throws Exception {
    return true;
  }


  @Override
  public void afterHandshake(ServerHttpRequest serverHttpRequest,
 ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {
    ...
  }
}
Şöyle yaparız.
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
  registry.addEndpoint("/agent").addInterceptors(new WSHandshakeInterceptor())
    .withSockJS();
}