Heim > Fragen und Antworten > Hauptteil
Ich versuche, meinen React.jsocks-Client mit meinen Spring Boot-Backend-Web-Sockets zu verbinden, aber ich kann sie nicht verbinden. Es werden mir auf der Chrome-Konsole folgende Fehler angezeigt:
Chrome-Konsolenfehler
Ich habe keine Fehler in meinem Spring Boot-Teil, aber es gibt einige Warnungen wie:
Spring Boot Console
Warum ich sie nicht verbinden kann. Mein React.js-Teil sieht so aus:
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);
Und mein Spring Boot-Konfigurationskurs:
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"); } }
Ähnlich habe ich für den Web-Socket-Controller diesen Teil geschrieben:
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()); }); } }
Ich habe versucht, Socken zu verwenden, um mein React.js-Frontend und Spring Boot-Backend zu verbinden, aber es geht nicht
Meine process.env.REACT_APP_ROOT_URL lautet: http://localhost:1998 und @Value("${blog.app.front}") Private String-URL; der Wert dieses Teils ist: http://localhost:3000
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 的示例。