是否可以将Java的Socket API用于Spring Boot web应用程序?

是否可以将Java的Socket API用于Spring Boot web应用程序?,java,spring,spring-boot,sockets,serversocket,Java,Spring,Spring Boot,Sockets,Serversocket,当我在谷歌上搜索这个主题时,我发现的只是与WebSocket相关的东西。我想使用Java的Socket API在客户机和服务器之间发送和接收数据(服务器始终是spring boot web应用程序,客户机可以是也可以不是) 我将服务器应用程序设计为在执行java-jar server.war时在端口4444上运行,将客户端设计为在执行java-jar client.war时在端口3333上运行。服务器应在端口5555上侦听 到目前为止,我为服务器提供了: 控制器 @Controller publ

当我在谷歌上搜索这个主题时,我发现的只是与WebSocket相关的东西。我想使用Java的Socket API在客户机和服务器之间发送和接收数据(服务器始终是spring boot web应用程序,客户机可以是也可以不是)

我将服务器应用程序设计为在执行
java-jar server.war
时在端口4444上运行,将客户端设计为在执行
java-jar client.war
时在端口3333上运行。服务器应在端口5555上侦听

到目前为止,我为服务器提供了:

控制器

@Controller
public class Home {
  ServerSocket s;

  Integer PORT = 5555;

  @RequestMapping("/")
  public String index() {
    return "index";
  }

  @RequestMapping("/open_connection")
  @ResponseBody
  public void open_connection() throws Exception {
    s = new ServerSocket(PORT);
  }

  @RequestMapping("/close_connection")
  @ResponseBody
  public void close_connection() throws Exception {
    s.close();
  }

  @RequestMapping("/listen_connection")
  @ResponseBody
  public String listen_connection() throws Exception {
    Socket socket = s.accept();
    DataInputStream dis=new DataInputStream(socket.getInputStream());
    String  str = (String) dis.readUTF();
    socket.close();
    return str;
  }
}
@Controller
public class Home {
  String HOST = "localhost";

  Integer PORT = 5555;

  @RequestMapping("/")
  public String index() {
    return "index";
  }

  @RequestMapping(value="/send_data", method=RequestMethod.POST)
  @ResponseBody
  public void send_data(@RequestParam("data") String data) throws Exception {
    Socket socket = new Socket(HOST, PORT);
    DataOutputStream dout = new DataOutputStream(socket.getOutputStream());
    dout.writeUTF(data);
    dout.flush();
    dout.close();
    socket.close();
  }
}
通过以下javascript代码调用这些方法:

var isOpen = false;

function open_connection(e) {
  var url = e.dataset.url;
  var oReq = new XMLHttpRequest();

  oReq.onload = function(ev) {
    var responseText = oReq.response;
    isOpen = true;
    document.querySelector('.btn-success').style.display = 'none';
    document.querySelector('.btn-danger').style.display = 'block';
  }

  oReq.open("GET", url);
  oReq.send();
}

function close_connection(e) {
  var url = e.dataset.url;
  var oReq = new XMLHttpRequest();

  oReq.onload = function(ev) {
    var responseText = oReq.response;
    isOpen = false;
    document.querySelector('.btn-danger').style.display = 'none';
    document.querySelector('.btn-success').style.display = 'block';
  }

  oReq.open("GET", url);
  oReq.send();
}

function listen_connection(e) {
  var url = document.querySelector('.container').dataset.url;

  if(isOpen) {
    while(true) {
      var oReq = new XMLHttpRequest();

      oReq.onload = function(ev) {
        var responseText = oReq.response;
        if(responseText === 'quit') {
          break;
        } else {
          var item = document.createElement('li');
          item.setAttribute('class', 'list-group-item');
          item.innerText = responseText
          document.querySelector('.list-group').addChild(item);
        }
      }

      oReq.open("GET", url);
      oReq.send();
    }
  }
}
function send(e) {
  var url = e.dataset.url;
  var oReq = new XMLHttpRequest();

  oReq.onload = function(ev) {
    var responseText = oReq.response;
    document.querySelector('.form-control').value = '';

  }

  oReq.open("POST", url);
  var formData = new FormData();
  formData.append("data", document.querySelector('.form-control').value)
  oReq.send(formData);
}
当我从html视图调用这个方法时,open connection和close connection不会给我任何错误。我不知道如何开始侦听连接以从客户端接收数据(我尝试从open_connection调用listen_connection,但这样在调用open connection方法时会使浏览器崩溃)

在客户端中,我有以下内容:

控制器

@Controller
public class Home {
  ServerSocket s;

  Integer PORT = 5555;

  @RequestMapping("/")
  public String index() {
    return "index";
  }

  @RequestMapping("/open_connection")
  @ResponseBody
  public void open_connection() throws Exception {
    s = new ServerSocket(PORT);
  }

  @RequestMapping("/close_connection")
  @ResponseBody
  public void close_connection() throws Exception {
    s.close();
  }

  @RequestMapping("/listen_connection")
  @ResponseBody
  public String listen_connection() throws Exception {
    Socket socket = s.accept();
    DataInputStream dis=new DataInputStream(socket.getInputStream());
    String  str = (String) dis.readUTF();
    socket.close();
    return str;
  }
}
@Controller
public class Home {
  String HOST = "localhost";

  Integer PORT = 5555;

  @RequestMapping("/")
  public String index() {
    return "index";
  }

  @RequestMapping(value="/send_data", method=RequestMethod.POST)
  @ResponseBody
  public void send_data(@RequestParam("data") String data) throws Exception {
    Socket socket = new Socket(HOST, PORT);
    DataOutputStream dout = new DataOutputStream(socket.getOutputStream());
    dout.writeUTF(data);
    dout.flush();
    dout.close();
    socket.close();
  }
}
通过以下javascript代码调用这些方法:

var isOpen = false;

function open_connection(e) {
  var url = e.dataset.url;
  var oReq = new XMLHttpRequest();

  oReq.onload = function(ev) {
    var responseText = oReq.response;
    isOpen = true;
    document.querySelector('.btn-success').style.display = 'none';
    document.querySelector('.btn-danger').style.display = 'block';
  }

  oReq.open("GET", url);
  oReq.send();
}

function close_connection(e) {
  var url = e.dataset.url;
  var oReq = new XMLHttpRequest();

  oReq.onload = function(ev) {
    var responseText = oReq.response;
    isOpen = false;
    document.querySelector('.btn-danger').style.display = 'none';
    document.querySelector('.btn-success').style.display = 'block';
  }

  oReq.open("GET", url);
  oReq.send();
}

function listen_connection(e) {
  var url = document.querySelector('.container').dataset.url;

  if(isOpen) {
    while(true) {
      var oReq = new XMLHttpRequest();

      oReq.onload = function(ev) {
        var responseText = oReq.response;
        if(responseText === 'quit') {
          break;
        } else {
          var item = document.createElement('li');
          item.setAttribute('class', 'list-group-item');
          item.innerText = responseText
          document.querySelector('.list-group').addChild(item);
        }
      }

      oReq.open("GET", url);
      oReq.send();
    }
  }
}
function send(e) {
  var url = e.dataset.url;
  var oReq = new XMLHttpRequest();

  oReq.onload = function(ev) {
    var responseText = oReq.response;
    document.querySelector('.form-control').value = '';

  }

  oReq.open("POST", url);
  var formData = new FormData();
  formData.append("data", document.querySelector('.form-control').value)
  oReq.send(formData);
}
这里的问题是,当我点击调用这个方法时,我得到了一个错误403(禁止)


任何人都可以告诉我我做错了什么?

可以使用
SpringIntegration
,可以找到TCP和UDP文档。但总而言之,您可以使用集成流将消息/通信从一种形式转换为另一种形式,并实现一系列标准的企业集成模式。

关键在于使用
SpringIntegration
,可以找到TCP和UDP文档。但总而言之,您可以使用集成流将消息/通信从一种形式转换为另一种形式,并实现一系列标准的企业集成模式。

Spring boot应用程序毕竟只是一个java应用程序,通常会公开一些Http接口,但并不总是这样(想想从消息传递系统获取输入的应用程序)

因此,从技术上讲,没有什么可以阻止您使用普通套接字

因此,您可以创建(可能是范围为Singleton的),这样在应用程序上下文中只有一个这样的bean

因为SpringBoot管理应用程序的生命周期,所以当应用程序宕机时,您甚至可以优雅地关闭服务器套接字

只要服务器套接字端口可用,并且您自己实现通信协议,所有这些都将起作用。这是基础。请记住,这种通信方式是极低级别的,因此您不会进行监视,必须处理线程池(如果服务器上并行运行的请求太多怎么办)等等


Spring集成或类似于Camel的框架可能以一种您可以在生产中实际使用的方式来包装它,但我认为这超出了问题的范围。

Spring boot应用程序毕竟只是一个java应用程序,通常会公开一些Http接口,但并不总是这样(想想从消息传递系统获取输入的应用程序)

因此,从技术上讲,没有什么可以阻止您使用普通套接字

因此,您可以创建(可能是范围为Singleton的),这样在应用程序上下文中只有一个这样的bean

因为SpringBoot管理应用程序的生命周期,所以当应用程序宕机时,您甚至可以优雅地关闭服务器套接字

只要服务器套接字端口可用,并且您自己实现通信协议,所有这些都将起作用。这是基础。请记住,这种通信方式是极低级别的,因此您不会进行监视,必须处理线程池(如果服务器上并行运行的请求太多怎么办)等等


Spring集成或类似于Camel的框架可能会以一种您可以在生产中实际使用的方式来包装它,但我认为这超出了问题的范围。

为什么?如果您所做的只是发送一个字符串,那么三个帖子和一个套接字是一种非常复杂的方式来完成它。我不会使用它来发送一个字符串之后,这只是一个开始。为什么?如果你所做的只是发送一个字符串,那么三个帖子和一个套接字是一个非常复杂的方式来完成它。我以后不会使用发送一个字符串,这只是一个开始。