Можно ли использовать Socket API из Java с веб-приложением Spring-Boot? - PullRequest
0 голосов
/ 22 января 2020

Когда я гуглю эту тему, все, что я обнаружил, - это материал, связанный с веб-сокетами. Я хочу использовать Socket API из Java для отправки и получения данных между клиентом и сервером (сервер всегда является веб-приложением с начальной загрузкой, клиент может быть или нет).

Я разработал серверное приложение для запуска на порту 4444 при выполнении java -jar server.war и клиент для запуска на порту 3333 при выполнении java -jar client.war. Сервер должен прослушивать порт 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;
  }
}

методы называются через этот 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();
    }
  }
}

Когда я вызываю эти методы из представления html, открытое соединение и закрытое соединение не дают мне ошибок. Я понятия не имею, как начать прослушивать соединение для получения данных от клиентов (я пытаюсь вызвать listen_connection из open_connection, но при этом я вызываю sh браузер, когда вызываю метод открытого соединения).

В клиент, у меня есть это:

контроллер

@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 код:

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 (запрещено).

Кто-нибудь может сказать мне, что я делаю здесь неправильно?

Ответы [ 2 ]

0 голосов
/ 29 января 2020

Весеннее загрузочное приложение, в конце концов, является просто java приложением, которое обычно предоставляет некоторый интерфейс Http, но не всегда (подумайте о каком-то приложении, которое получает свои данные, скажем, от системы обмена сообщениями).

Так что технически нет ничего, что могло бы помешать вам использовать простые сокеты.

Так что вы можете создавать (возможно, из области действия Singleton, чтобы в контексте приложения был только один такой компонент). Этот компонент во время инициализации откроет сокет сервера и примет соединения.

Поскольку весенняя загрузка управляет жизненным циклом приложения, вы даже можете изящно закрыть сокет сервера, когда приложение выйдет из строя.

Все это будет работать, пока доступен порт сокета сервера, и вы сами реализуете протокол связи. Это основа. Имейте в виду, что этот способ связи является чрезвычайно низкоуровневым, поэтому вам не нужно осуществлять мониторинг, вам придется иметь дело с пулами потоков (что если слишком много запросов на параллельном сервере), et c.

Spring Integration или фреймворки, такие как Camel, возможно, обернут все это таким образом, что вы действительно сможете использовать его в работе, но я думаю, что это выходит за рамки вопроса.

0 голосов
/ 29 января 2020

Перейти к использованию SpringIntegration, документацию по TCP и UDP можно найти здесь . Но в итоге вы можете использовать потоки интеграции для преобразования сообщений / сообщений из одной формы в другую и реализовать набор стандартных корпоративных шаблонов интеграции.

...