SpringBoot webSocket 은 방송,점 대 점 메시지,안 드 로 이 드 수신 을 실현 합 니 다.
20586 단어 springbootwebsocket
SpringBoot 에서 사용 하 는 웹 소켓 프로 토 콜 은 표준 웹 소켓 프로 토 콜 이 아니 라 STOMP 라 는 프로 토 콜 을 사용 합 니 다.
1.1 STOMP 프로 토 콜 설명
STOMP,Streaming Text Orientated Message Protocol 은 스 트림 텍스트 지향 메시지 프로 토 콜 로 MOM(Message Oriented Middleware,메시지 지향 미들웨어)을 위 한 간단 한 텍스트 프로 토 콜 입 니 다.
이것 은 STOMP 클 라 이언 트 가 임의의 STOMP 메시지 에이전트(Broker)와 OpenWire(바 이 너 리 프로 토 콜)와 같은 상호작용 을 할 수 있 는 연결 형식 을 제공 합 니 다.
디자인 이 간단 하고 클 라 이언 트 를 개발 하기 쉬 우 므 로 다양한 언어 와 다양한 플랫폼 에서 광범 위 하 게 응용 된다.그 중 가장 유행 하 는 STOMP 메시지 에이 전 트 는 Apache ActiveMQ 다.
1.2 구축
저 는 Inject idea 가 만 든 springBoot websocket 을 사 용 했 습 니 다.익숙 한 gradle 이 아니 라 Maven 방식 으로 만 들 었 습 니 다.
프로젝트 구 조 는 다음 과 같다.
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.drawthink</groupId>
<artifactId>websocketdemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>webSocketdemo</name>
<description>webSocketDemo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Application:
package com.drawthink;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class WebSocketdemoApplication {
public static void main(String[] args) {
SpringApplication.run(WebSocketdemoApplication.class, args);
}
}
WebSocketConfig
package com.drawthink.websocket;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
/**
* Created by lincoln on 16-10-25
*/
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
// socketJs , hello,
stompEndpointRegistry.addEndpoint("/hello").setAllowedOrigins("*").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// Broker
registry.enableSimpleBroker("/topic","/user");
// ( )
registry.setApplicationDestinationPrefixes("/app/");
// ( ), , /user/
//registry.setUserDestinationPrefix("/user/");
}
}
WebSocketController
package com.drawthink.websocket.controller;
import com.drawthink.message.ClientMessage;
import com.drawthink.message.ServerMessage;
import com.drawthink.message.ToUserMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
/**
* Created by lincoln on 16-10-25
*/
@Controller
public class WebSocketController {
@MessageMapping("/welcome")
//SendTo Broker
@SendTo("/topic/getResponse")
public ServerMessage say(ClientMessage clientMessage){
//
System.out.println("clientMessage.getName() = " + clientMessage.getName());
return new ServerMessage("Welcome , "+clientMessage.getName()+" !");
}
// SimpMessagingTemplate
@Autowired
private SimpMessagingTemplate messagingTemplate;
@MessageMapping("/cheat")
// /user/{userId}/message
// /user/ , , config setUserDestinationPrefix
public void cheatTo(ToUserMessage toUserMessage){
//
System.out.println("toUserMessage.getMessage() = " + toUserMessage.getMessage());
System.out.println("toUserMessage.getUserId() = " + toUserMessage.getUserId()); messagingTemplate.convertAndSendToUser(toUserMessage.getUserId(),"/message",toUserMessage.getMessage());
}
}
Vo
package com.drawthink.message;
/**
* Created by lincoln on 16-10-25
*/
public class ClientMessage {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.drawthink.message;
/**
* Created by lincoln on 16-10-25
*/
public class ServerMessage {
private String responseMessage;
public ServerMessage(String responseMessage) {
this.responseMessage = responseMessage;
}
public String getResponseMessage() {
return responseMessage;
}
public void setResponseMessage(String responseMessage) {
this.responseMessage = responseMessage;
}
}
package com.drawthink.message;
/**
* Created by lincoln on 16-10-25
*/
public class ToUserMessage {
private String userId;
private String message;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
안 드 로 이 드 클 라 이언 트STOMP 프로 토 콜 은 안 드 로 이 드 시스템 에서 기본적으로 구현 되 지 않 았 으 므 로 스스로 실행 해 야 합 니 다.그러나 좋 은 소식 은 개원 대신 들 이 안 드 로 이 드 에서 STOMP 프로 토 콜 을 사용 하 는 실현 을 완 료 했 기 때문에 우 리 는 사용 만 하면 된다 는 것 이다.
주소
세우다
build.gradle(app)
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "24.0.3"
defaultConfig {
applicationId "com.drawthink.websocket"
minSdkVersion 16
targetSdkVersion 24
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:24.2.1'
testCompile 'junit:junit:4.12'
// STOMP Android
compile 'com.github.NaikSoftware:StompProtocolAndroid:1.1.1'
//StompProtocolAndroid webSocket
compile 'org.java-websocket:Java-WebSocket:1.3.0'
}
라디오 수신 실례:
package com.drawthink.websocket;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import org.java_websocket.WebSocket;
import rx.Subscriber;
import rx.functions.Action1;
import ua.naiksoftware.stomp.LifecycleEvent;
import ua.naiksoftware.stomp.Stomp;
import ua.naiksoftware.stomp.client.StompClient;
import ua.naiksoftware.stomp.client.StompMessage;
import static android.content.ContentValues.TAG;
public class MainActivity extends AppCompatActivity {
private TextView serverMessage;
private Button start;
private Button stop;
private Button send;
private EditText editText;
private StompClient mStompClient;
private Button cheat;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindView();
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// client
createStompClient();
//
registerStompTopic();
}
});
send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mStompClient.send("/app/welcome","{\"name\":\""+editText.getText()+"\"}")
.subscribe(new Subscriber<Void>() {
@Override
public void onCompleted() {
toast(" ");
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
toast(" ");
}
@Override
public void onNext(Void aVoid) {
}
});
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mStompClient.disconnect();
}
});
cheat.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this,CheatActivity.class));
if(mStompClient != null) {
mStompClient.disconnect();
}
finish();
}
});
}
private void showMessage(final StompMessage stompMessage) {
runOnUiThread(new Runnable() {
@Override
public void run() {
serverMessage.setText("stomp command is --->"+stompMessage.getStompCommand() +" body is --->"+stompMessage.getPayload());
}
});
}
// client
private void createStompClient() {
mStompClient = Stomp.over(WebSocket.class, "ws://192.168.0.46:8080/hello/websocket");
mStompClient.connect();
Toast.makeText(MainActivity.this," 192.168.0.46:8080",Toast.LENGTH_SHORT).show();
mStompClient.lifecycle().subscribe(new Action1<LifecycleEvent>() {
@Override
public void call(LifecycleEvent lifecycleEvent) {
switch (lifecycleEvent.getType()) {
case OPENED:
Log.d(TAG, "Stomp connection opened");
toast(" ");
break;
case ERROR:
Log.e(TAG, "Stomp Error", lifecycleEvent.getException());
toast(" ");
break;
case CLOSED:
Log.d(TAG, "Stomp connection closed");
toast(" ");
break;
}
}
});
}
//
private void registerStompTopic() {
mStompClient.topic("/topic/getResponse").subscribe(new Action1<StompMessage>() {
@Override
public void call(StompMessage stompMessage) {
Log.e(TAG, "call: " +stompMessage.getPayload() );
showMessage(stompMessage);
}
});
}
private void toast(final String message) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,message,Toast.LENGTH_SHORT).show();
}
});
}
private void bindView() {
serverMessage = (TextView) findViewById(R.id.serverMessage);
start = (Button) findViewById(R.id.start);
stop = (Button) findViewById(R.id.stop);
send = (Button) findViewById(R.id.send);
editText = (EditText) findViewById(R.id.clientMessage);
cheat = (Button) findViewById(R.id.cheat);
}
}
점대 점
package com.drawthink.websocket;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import org.java_websocket.WebSocket;
import rx.Subscriber;
import rx.functions.Action1;
import ua.naiksoftware.stomp.LifecycleEvent;
import ua.naiksoftware.stomp.Stomp;
import ua.naiksoftware.stomp.client.StompClient;
import ua.naiksoftware.stomp.client.StompMessage;
import static android.content.ContentValues.TAG;
public class CheatActivity extends AppCompatActivity {
private EditText cheat;
private Button send;
private LinearLayout message;
private StompClient mStompClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cheat);
bindView();
createStompClient();
registerStompTopic();
send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// /app/cheat Json
mStompClient.send("/app/cheat","{\"userId\":\"lincoln\",\"message\":\""+cheat.getText()+"\"}")
.subscribe(new Subscriber<Void>() {
@Override
public void onCompleted() {
toast(" ");
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
toast(" ");
}
@Override
public void onNext(Void aVoid) {
}
});
}
});
}
private void bindView() {
cheat = (EditText) findViewById(R.id.cheat);
send = (Button) findViewById(R.id.send);
message = (LinearLayout) findViewById(R.id.message);
}
private void createStompClient() {
mStompClient = Stomp.over(WebSocket.class, "ws://192.168.0.46:8080/hello/websocket");
mStompClient.connect();
Toast.makeText(CheatActivity.this," 192.168.0.46:8080",Toast.LENGTH_SHORT).show();
mStompClient.lifecycle().subscribe(new Action1<LifecycleEvent>() {
@Override
public void call(LifecycleEvent lifecycleEvent) {
switch (lifecycleEvent.getType()) {
case OPENED:
Log.d(TAG, "Stomp connection opened");
toast(" ");
break;
case ERROR:
Log.e(TAG, "Stomp Error", lifecycleEvent.getException());
toast(" ");
break;
case CLOSED:
Log.d(TAG, "Stomp connection closed");
toast(" ");
break;
}
}
});
}
// /user/xiaoli/message
private void registerStompTopic() {
mStompClient.topic("/user/xiaoli/message").subscribe(new Action1<StompMessage>() {
@Override
public void call(StompMessage stompMessage) {
Log.e(TAG, "call: " +stompMessage.getPayload() );
showMessage(stompMessage);
}
});
}
private void showMessage(final StompMessage stompMessage) {
runOnUiThread(new Runnable() {
@Override
public void run() {
TextView text = new TextView(CheatActivity.this);
text.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
text.setText(System.currentTimeMillis() +" body is --->"+stompMessage.getPayload());
message.addView(text);
}
});
}
private void toast(final String message) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(CheatActivity.this,message,Toast.LENGTH_SHORT).show();
}
});
}
}
코드 가 어 지 러 우 니 설명해 주세요.1.STOMP 를 사용 할 때 관건 은 구독 을 발표 하 는 관계 이 고 메시지 큐 를 사용 한 적 이 있 습 니 다.예 를 들 어 rabbitMQ 는 쉽게 이해 할 수 있 습 니 다.
서버 쪽 웹 소켓 Config.자바 파일 은 게시 물 을 구독 하 는 경로 관 계 를 제어 합 니 다.
2.websocket 의 경 로 는 이 예 에서 뉴스:/192.168.0.46:8080/hello/websocket 경 로 를 설명 합 니 다./hello 는 WebSocket Config 의 stompEndpoint Registry.addEndpoint("/hello").setAllowedOrigins(").withSockJS()입 니 다.*확실한 것 은 여러 개의 endpoint 가 있 으 면 이곳 의 경로 도 이에 따라 달라 질 것 이다.
3.발표 경로
정 보 를 발표 하 는 경 로 는 웹 소켓 Config 의 setapplicationDestinationPrefixes("/app/")입 니 다.Controller 에서@Message Mapping("/welcome")과 조합 하여 확 정 했 습 니 다.
예 를 들 어 방송 메 시 지 를 보 내 는 경 로 는/app/welcome 입 니 다.
예 를 들 어 점 대 점 메 시 지 를 보 내 면 경 로 는/app/cheat 입 니 다.
4.메시지 구독 경로
구독 브로커 는 WebSocketConfig 의 registry.enableSimpleBroker("/topic","/user")에서 유래 합 니 다.이 곳 은 두 개의 broker 를 열 었 습 니 다.구체 적 인 구독 서비스 경 로 는 Controller 기반@SendTo("/topic/getResponse")나 SimpMessagingTemplate 에서 지정 합 니 다.(주:여기 서 서버 와 클 라 이언 트 는 구독 경 로 를 약정 해 야 합 니 다)
5.심장 박동
구독 게시 모델 의 심장 박동 은 매우 간단 합 니 다.클 라 이언 트 는 지정 한 심장 박동 경로 에 심장 박동 을 보 냅 니 다.서버 처리,서버 는 지정 한 구독 경 로 를 사용 하여 클 라 이언 트 에 게 심장 박동 을 보 내 면 됩 니 다.Socket 이 없 기 때문에 연결 여 부 를 기록 하면 됩 니 다.클 라 이언 트 를 다시 연결 하면 됩 니 다.
본인 의 풋내기,분명 뭔 가 알 지 못 한 부분 이 있 을 것 입 니 다.잘못 이 있 으 면 큰 신 이 고 쳐 주 십시오.
코드 다운로드 주소:StompProtocolAndroid_jb51.rar
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin Springboot -- 파트 14 사용 사례 REST로 전환하여 POST로 JSON으로 전환前回 前回 前回 記事 の は は で で で で で で を 使っ 使っ 使っ て て て て て リクエスト を を 受け取り 、 reqeustbody で 、 その リクエスト の ボディ ボディ を を 受け取り 、 関数 内部 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.