Продолжая протокол STOMP для Websocket сегодня, из-за его простой конструкции и легкости использования при разработке клиентов его можно увидеть на многих языках, и он не является «эксклюзивным» для websocket.
определение
STOMP (простой/потоковый протокол обмена текстовыми сообщениями), простой (потоковый) протокол обмена текстовыми сообщениями. Протокол, принадлежащий очереди сообщений, чем-то похожий на jms.
эффект
Предоставляет формат тела сообщения, позволяющий клиентам STOMP (конечным точкам) взаимодействовать с любым брокером сообщений STOMP (брокером сообщений) для достижения асинхронной передачи сообщений между клиентами.
Знакомство с персонажами
Источник изображения "Весна в действии"
- Клиент-производитель: отправить сообщение получателю;
- Потребительский клиент: получайте сообщения, отправленные подписанным пунктом назначения;
- Канал запроса: пул потоков, который получает сообщения, отправленные производителями;
- Соответствующий канал: пул потоков, который отправляет сообщения потребителям;
- Брокер: диспетчер очереди сообщений.Записывает, какие клиенты подписываются на какой пункт назначения.
- Адрес назначения приложения: Прежде чем сообщение, отправленное на этот тип адреса назначения, достигнет брокера, оно будет перенаправлено на метод, написанный приложением.Это эквивалентно перехвату сообщения, поступающего в брокер один раз, чтобы выполнить некоторую бизнес-обработку сообщение———"/app" на картинке
- Адрес назначения, не относящийся к приложению: сообщения, отправленные на этот тип адреса назначения, будут направляться непосредственно брокеру и не будут перехвачены приложением — «/topic» на рисунке.
Технологический поток
- Производитель отправляет сообщение получателю
- запросить канал для приема сообщений
- Если адрес назначения является адресом назначения приложения (/app), перейдите к соответствующему бизнес-методу, написанному самим приложением для обработки, а затем перейдите к брокеру.
- Если адрес назначения не является адресом назначения (/topic), перейдите непосредственно к broker.broker, чтобы создать сообщение, а затем отправить сообщение всем потребителям, подписавшимся на этот адрес назначения, через соответствующий канал.
Код
Следующее использует SpringSecurity и WebSocket-STOMP для реализации функции обмена сообщениями "точка-точка":
Включить функцию STOMP
@Configuration
@EnableWebSocketMessageBroker//开启消息代理
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
/**
* 建立连接点信息
* @param registry
*/
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws/ep").withSockJS();
registry.setApplicationDestinationPrefixes("/app");
}
/**
* 配置消息队列
* 基于内存的STOMP消息代理
* @param registry
*/
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/queue");
}
}
- Зарегистрируйте «/ws/ep» как конечную точку STOMP. Клиенты должны подключаться к этой конечной точке, прежде чем подписываться или публиковать сообщения по пути назначения.
- Сообщения, начинающиеся с /app, будут направляться методам, аннотированным с помощью @MessageMapping или @SubscribeMapping;
- Сообщения, начинающиеся с /queue, будут отправлены брокеру STOMP.В зависимости от выбранного брокера STOMP необязательный префикс адресата также будет ограничен;
- Сообщения, начинающиеся с /user, будут перенаправлять сообщение в место назначения, уникальное для пользователя.
Обработка сообщений STOMP
пользовательский протокол связи
@Controller
public class WScontroller {
@Autowired//消息发送模板
SimpMessagingTemplate simpMessagingTemplate;
@MessageMapping("/ws/chat")
public void receiveMessage(String message, Principal principal) {
String[] split = message.split(";");
HashMap<String, Object> map = new HashMap<>();
map.put("username",split[1]);
map.put("msg",split[0]);
simpMessagingTemplate.convertAndSendToUser(split[1], "/queue/msg",map);
}
- Получить сообщение, отправленное клиентом, параметром является само сообщение
message- Аннотации @MessageMapping или @SubscribeMapping могут обрабатывать сообщения, отправленные клиентом, и выбирать, имеет ли метод возвращаемое значение.
- @MessageMapping указывает, что пунктом назначения является «/app/ws/chat» (префикс «/app» подразумевается, поскольку мы настроили его как префикс назначения для приложения).
- Протокол связи можно настроить - формат настраиваемых параметров
- Может получать данные в формате json, не нужно добавлять дополнительную аннотацию @Requestbody при передаче данных josn
- Отправитель сообщения не передается из внешнего интерфейса, а получается из springsecurity, чтобы предотвратить олицетворение внешнего интерфейса.
- Если аннотированный метод контроллера @MessageMapping имеет возвращаемое значение, возвращаемое значение будет отправлено брокеру сообщений, но с префиксом «/topic».
- Переопределите пункт назначения, аннотировав метод с помощью @SendTo.
Реализация клиента
Код клиента (UVE)
<template>
<div>
<div>
<div v-for="(m,index) in ms">{{m.username}}:{{m.msg}}</div>
</div>
<el-input v-model="msg"></el-input>
<el-button @click="sendMsg"></el-button>
</div>
</template>
<script>
import "../../lib/sockjs"
import "../../lib/stomp"
export default {
name: "FriendChat",
data() {
return {
msg: '',
ms: [],
stomp: null
};
},
mounted() {
this.intCon();
},
methods: {
// 建立连接
initCon() {
let _this = this;
this.stomp = Stomp.over(new SockJS("/ws/ep"));
this.stomp.connect({},success=>{
_this.stomp.subscribe("/user/queue/msg",msg=>{
_this.ms.push(JSON.parse(msg.body));
})
},fail=>{
})
},
// 发送消息
sendMsg() {
this.stomp.send("/ws/chat",{},this.msg)
}
}
}
</script>
<style scoped>
</style>