搜尋

首頁  >  問答  >  主體

Websocket與spring boot和react.js的連接

我正在嘗試將我的react.jsocks客戶端連接到我的spring boot後端Web套接字,但我無法連接它們,它在chrome控制台上給了我一些錯誤,如下所示:

chrome 控制台錯誤

我的 Spring Boot 部分沒有任何錯誤,但有一些類似的警告:

彈簧啟動控制台

為什麼我無法連接它們我的react.js部分是這樣的:

import background from'../Styles/Background.module.css'
import formdesign from'../Styles/FormDesign.module.css'
import Bounce from 'react-reveal/Bounce';
import cookies from 'js-cookie'
import Menustyle from'../Styles/Menu.module.css'
import {useLocation, useNavigate} from 'react-router-dom';
import { useState ,useEffect } from 'react';
import swal from 'sweetalert';
import Swal from 'sweetalert2'
import { connect } from 'react-redux';
import { Oval } from 'react-loader-spinner';
import {GetWithAuth ,GetWithRefresh,beforeRegister,registerWithMail, beforeLogin} from '../Services/HttpServices';
import { isUserBlockExist } from '../Services/UserPrefs';
import SockJS from 'sockjs-client';
import { over } from 'stompjs';
let number = 1;
const Login  = (props)=>{
  const navigate = useNavigate();
  const location = useLocation();
  const [isLoading, setIsLoading] = useState(true);
  const [allState,setAllState] = useState({
    title:props.title,
    message:props.message,
    button:props.button,
    show:true
  });
   const beforeLoad = async ()=>{ 
    let sock = new SockJS(`${process.env.REACT_APP_ROOT_URL}/wss`);
    let stompClient = over(sock);
    stompClient.connect({},function(frame){
      console.log("Connected : "+frame);
      //stompClient.subscribe("/user-connect/user",this.onPrivateMessage);
    });
    try{
    console.log(process.env.REACT_APP_ROOT_URL);
    let response = await GetWithAuth(`${process.env.REACT_APP_ROOT_URL}/auth/route`,"/homepage",props.jwtsession);
    if(response.route == "/"){
      document.body.className = background.deneme;
      props.setJwtSession("");
      //localStorage.removeItem("jwtsession");
    }
    else{
      document.body.className = Menustyle.deneme;
    }
    setIsLoading(false);
    navigate(response.route);
     }
     catch{
      window.location.reload();
     }
    }
      const handleClick = ()=>{
          if(allState.show === false && number === 1){
              setAllState({show:true,message:"Have Account ?",title:"Sign-Up"});
            }
          else if(allState.show === false && number === 2){
            setAllState({show:true,message:"Don't Have Account ?",title:"Login"});
          }
          
      }
      const submit = async()=>{
        if(document.getElementById("password").value.trim().length ==0){
          swal({
            title: "Password Field Is Required!",
            text: "Please Write Your Password",
            icon: "error",
            button: "Close This Alert",
          });
        }
        else if(document.getElementById("username").value.trim().length ==0){
          swal({
            title: "Username Field Is Required!",
            text: "Please Write Your Username",
            icon: "error",
            button: "Close This Alert",
          });
        }
        else if(document.getElementById("username").value.trim().length >=15&&allState.title!="Login"){
          swal({
            title: "Username Can Not More Than 15 Characters",
            text: "Please Try Another Username",
            icon: "error",
            button: "Close This Alert",
          });
         }
       else if(document.getElementById("email")!=null && document.getElementById("email").value.trim().length ==0){
        swal({
          title: "E-Mail Field Is Required!",
          text: "Please Write Your E-Mail",
          icon: "error",
          button: "Close This Alert",
        });
     
       }
         else if(allState.title === "Sign-Up"){
          let postres = await beforeRegister(`${process.env.REACT_APP_ROOT_URL}/auth/beforeregister`,document.getElementById("username").value.trim(),document.getElementById("email").value,document.getElementById("password").value); 
          if(postres.created == true){
             Swal.fire({
              html:`<h1>Please Write The Code We Sent To Your Email</h1>
              <input type="text" id="code" class="swal2-input" placeholder="CODE" style="width:50%;">
              <button id="send" class="btn btn-success">
      SEND
    </button><br/><br/>
    You Have <strong></strong> seconds.<br/><br/>
              `,
              timer:90000,
              icon: "success",
              allowOutsideClick:false,
              showCancelButton:true,
              didOpen: ()=>{
                const content = Swal.getHtmlContainer()
                const $ = content.querySelector.bind(content)
                const send = $('#send');
                const code = $('#code');
                send.addEventListener("click",async()=>{
                  let postres2 =  await registerWithMail(`${process.env.REACT_APP_ROOT_URL}/auth/registerwithmail`,code.value.trim().toLowerCase());
          if(postres2.created == true){
            props.setJwtSession(postres2.accessToken);
            //localStorage.setItem("jwtsession",postres2.accessToken);
            navigate('/homepage');
            Swal.close();
          }
          else if(postres2.created == false){
            Swal.close();
            swal({
              title: postres2.error,
              text: "Please Check And Try Again",
              icon: "error",
              button: "Close This Alert",
            });
          }
              });
                Swal.showLoading();
                setInterval(() => {
                  Swal.getHtmlContainer().querySelector('strong')
                    .textContent = (Swal.getTimerLeft() / 1000)
                      .toFixed(0)
                }, 100)
             
            }})
         }
         else{
          swal({
            title: postres.error,
            text: "Please Check And Try Again",
            icon: "error",
            button: "Close This Alert",
          });
         }
        }
         else if(allState.title === "Login"){
          let postres = await beforeLogin(`${process.env.REACT_APP_ROOT_URL}/auth/beforelogin`,document.getElementById("username").value.trim(),document.getElementById("password").value);
          if(postres.created == true){
            Swal.fire({
              html:`<h1>Please Write The Code We Sent To Your Email</h1>
              <input type="text" id="code" class="swal2-input" placeholder="CODE" style="width:90%; margin-left:0px;">
              <button id="send" class="btn btn-success">
              SEND
              </button>
              <button id="close" class="btn btn-secondary">
      CLOSE
    </button><br/><br/>
    You Have <strong></strong> seconds.<br/><br/>
              `,
              timer:90000,
              icon: "success",
              allowOutsideClick:false,
              didOpen: ()=>{
                const content = Swal.getHtmlContainer()
                const $ = content.querySelector.bind(content)
                const send = $('#send');
                const code = $('#code');
                send.addEventListener("click",async()=>{
                let postres2 =  await registerWithMail(`${process.env.REACT_APP_ROOT_URL}/auth/loginwithmail`,code.value.trim().toLowerCase());
          if(postres2.created == true){
            props.setJwtSession(postres.accessToken.toString());
            console.log(postres.accessToken);
           navigate('/homepage');
            Swal.close();
          }
          else if(postres2.created == false){
            Swal.close();
            swal({
              title: postres2.error,
              text: "Please Check And Try Again",
              icon: "error",
              button: "Close This Alert",
            });
          }
              });
                Swal.showLoading();
                setInterval(() => {
                  Swal.getHtmlContainer().querySelector('strong')
                    .textContent = (Swal.getTimerLeft() / 1000)
                      .toFixed(0)
                }, 100)
             
            }})
          }
          else if(postres.created === false && postres.blocked == false){
            swal({
              title: postres.error,
              text: "Please Check And Try Again",
              icon: "error",
              button: "Close This Alert",
            });
            console.log(postres);
          }
          else{
            swal({
              title: postres.error,
              text: "Please Check And Try Again",
              icon: "error",
              button: "Close This Alert",
            });
          }
         }
      
    }
      useEffect(() =>{
        beforeLoad();
      },[]);
      useEffect( ()=>{
        setTimeout(() => {
              if(allState.show === true && number === 1){
                setAllState({show:false,message:"Have Account ?",title:"Sign-Up"});
                number = 2;
                console.log(allState.message);
              }
              else if(allState.show === true && number === 2){
                setAllState({show:false,message:"Don't Have Account ?",title:"Login"});
                number = 1;
            }
          }, 300);
      },[allState]);
      if (isLoading) {
        return <div className={formdesign.loading}>
          <Oval
          width="100"
          height="100"
          color="black"
          ariaLabel='loading'
          />
        </div>;
      }
        return(
            <div>
            <Bounce left opposite when={!allState.show}>
            <div className={allState.title =="Login" ? formdesign.formBack : formdesign.formBackSignUp}>
                <h1 className={formdesign.Title}>{allState.title}</h1>
                <input type="text" name = "username" placeholder={allState.title == 'Login' ? 'Username Or Email' : 'Username'} id='username'></input>
                {allState.title =="Sign-Up" &&
                <input type="text" name = "email" placeholder="E-Mail" id='email'></input>
                }
                <input type="password" name = "password" placeholder="Password" id='password'></input>
                <input type="button" value={allState.title} onClick = {submit} ></input>
                <p>{allState.message} <span style={{color:"blue",cursor:"pointer"}} onClick = {handleClick}>Click Here</span></p>
            </div>
            </Bounce>
            </div>
              
    );}
    const mapStateToProps = (state)=>{
      return{
        jwtsession:state.jwtsession
      }
    }
    const mapDispatchToProps = (dispatch) =>{
      return{
        setJwtSession: (jwtsession) =>{ dispatch({'type':'SET_JWTSESSION',jwtsession})}
      }
    }
              
export default connect(mapStateToProps,mapDispatchToProps) (Login);

和我的 Spring Boot 設定類別:

package com.project.blog.websocket;

import org.springframework.beans.factory.annotation.Value;
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 WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {

    @Value("${blog.app.front}")
    private String url;
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/wss").setAllowedOrigins(url).setAllowedOriginPatterns("*").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.setApplicationDestinationPrefixes("/app");
        registry.enableSimpleBroker("/user-connect");
        registry.setUserDestinationPrefix("/user");
    }


}

同樣對於網路套接字控制器我寫了這部分:

package com.project.blog.websocket;

import com.project.blog.entities.User;
import com.project.blog.repositories.UserRepository;
import com.project.blog.responses.ErrorSuccessResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;

import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;

@Controller
@RequiredArgsConstructor
public class WebSocketController {


    private final SimpMessagingTemplate simpMessagingTemplate;
    private final UserRepository userRepository;

    @MessageMapping("/message")
    private ErrorSuccessResponse receiveMessage(String user){
        ErrorSuccessResponse errorSuccessResponse = new ErrorSuccessResponse();
        errorSuccessResponse.setError("block oldu");
    simpMessagingTemplate.convertAndSendToUser(user,"/private",errorSuccessResponse);
    return errorSuccessResponse;
    }
    @Scheduled(fixedDelay = 1000)
    private void checkBlocks(){
        LocalDateTime now = LocalDateTime.now();
        List<User> users = userRepository.findBlockedUsers(now);

        users.stream().forEach(user->{
            receiveMessage(user.getUsername());
        });
    }
}

我嘗試使用襪子連接我的react.js前端和spring boot後端,但我做不到

我的 process.env.REACT_APP_ROOT_URL 是:http://localhost:1998 和@Value(“${blog.app.front}”) 私有字串 url;這部分值是:http://localhost:3000

P粉615829742P粉615829742276 天前470

全部回覆(1)我來回復

  • P粉759451255

    P粉7594512552024-03-27 13:24:23

    問題可能出在客戶端或伺服器端。第一步是能夠使用測試工具單獨測試伺服器。這並不容易,因為程式碼在 SockJS 上使用 STOMP 協定。

    您可能不需要使用 SockJS。請參閱將 STOMP 與 SockJS 結合使用。所以第一步是刪除 SockJS 的使用,看看它是否有效。

    下一步是取消 STOMP 的使用。一種更簡單的方法是僅使用純文字訊息。如果您這樣做,則可以使用命令列工具,例如 wscat 或 Chrome 瀏覽器外掛程式例如 WebSocketKing 來自行測試伺服器。一旦伺服器與測試工具一起工作,您就可以使用客戶端程式碼進行測試。

    我遇到了類似的問題,最終使用 JSON 訊息開發了自己的協議,以 WebSocket 文字訊息的形式發送。我可以使用 WebSocket King 單獨測試伺服器。捲動到 Brill Middleware 的末尾查看使用 WebSocket King 的範例。

    回覆
    0
  • 取消回覆