2016-07-25 2 views
0

간단한 Java Server Socket (PHP 및/또는 ASP 대신)을 사용하여 SSE (Server Sent Events)를 구현하고자합니다.Java를 사용하여 Simple SSE Server를 구현하는 방법은 무엇입니까?

이 서버는 브라우저에서 들어오는 요청을 수신 대기하고 처리기 스레드를 만들고 연결을 닫지 않고 요청 (헤더 전송)에 응답 한 다음 사용자 입력 (System.in)을 기다립니다. 메시지를 클라이언트로 전달하십시오.

물론 J2EE 라이브러리 (예 : 저지)를 사용하면 과도한 작업이 될 것입니다.

소스는 다음과 같다 :

import java.net.*; 
import java.io.*; 
import java.util.Scanner; 

public class Loc { 
public static void main (String[] args) throws IOException{ 
    ServerSocket ss = new ServerSocket(8888); 
    //listen to only one connection. 
    System.out.print("Waiting for connection..."); 

    Socket hp = ss.accept(); 
    System.out.println("Connected!"); 


    BufferedReader br = new BufferedReader(new InputStreamReader(hp.getInputStream()));  

    String line = ""; 
    while(br.ready() && (line=br.readLine()) != null) { //dumps request header. 
     System.out.println(line); 
    } 

    Thread handler = new Thread(new ClientHandler(hp)); 
    handler.start(); 
    try { 
     handler.join(); 
    }catch(InterruptedException e){ 

    } 
    System.out.println("Server stopped."); 
    } 
} 

class ClientHandler implements Runnable{ 

Socket toClient; 

public ClientHandler(Socket s){ 
    this.toClient = s; 
} 

public void run() { 
    try { 
     BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //server input (also forwards it to client) 
     BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(toClient.getOutputStream())); 

     // response header. 
     String response = "HTTP/1.1 200 OK\n"+ 
     "Server: Maknyos-Server/1.0\n"+ 
     "Cache-Control: no-cache,public\n"+ 
     "Content-Type: text/event-stream\n"+ 
     "Connection: keep-alive\n"+ 
     "Language: en-US\n"+ 
     "Charset: UTF-8\n"+ 
     "\n"; //two line break as header ending. 

     bw.write(response); 
     bw.flush(); 

     String input = ""; 
     while ((input = br.readLine()) != null) { //one directional message to client (browser), via cmd. 

      bw.write(input+'\n'); 
      bw.flush(); 
      if("close".equalsIgnoreCase(input)){ 
       break; 
      } 
     } 

     toClient.close(); 
    }catch(IOException e){ 
     System.out.println("IOEXception! "+e); 
    } 
    } 

이 클라이언트입니다.

<h1>Hullo World!</h1> 
<script type="text/javascript"> 

    var es = new EventSource("http://localhost:8888"); 
    es.onmessage = function (event) { 
     alert(event.data); 
    }; 
</script> 

html 페이지를 열면 내 서버에서 http 요청 헤더 (명령 줄)를 볼 수 있습니다. 내 서버가 나는 그 두 클라이언트와 서버 사이에, 내가 할 어떤 문제입니다 설명하려고합니다

HTTP/1.1 200 OK 
Server: Maknyos-Server/1.0 
Cache-Control: no-cache,public 
Content-Type: text/event-stream 
Connection: keep-alive 
Language: en-US 
Charset: UTF-8 


... 

로 회신. 아마도 프로토콜과 관련이 있을지 모르지만 확실하지 않습니다.

먼저, 응답 헤더를 끝내기 위해 머리말의 끝에 두 줄만 추가하면 (위 예제와 같이) Firefox 콘솔은 브라우저가 서버에 연결할 수 없다고 알려줍니다. 그러나 NET 콘솔에서 응답 요청을받습니다.

둘째, 응답 헤더를 끝내지 않고 테스트합니다 (이중 \ n 문자 없음).

둘 중 누구도 SSE를 브라우저에 전송하지 못했습니다.

편집, 다시 브라우저의 콘솔 창이 표시되면 다른 도메인에 요청할 수 없다는 메시지가 나타납니다.

이 프로그램은 로컬 호스트에서 실행 : 8888 하지만 난 (HTML 페이지에 대한)를 사용하여 웹 서버가 로컬 호스트에 : 당신이 봄 부팅을 사용하여 응용 프로그램을 작성하고 인스턴스를 반환하는 컨트롤러를 쓰기 I 제안 80

+0

"서버 보낸 이벤트"에 대한 링크를 포함 할 수 있습니까? 나는 그 용어에 익숙하지 않고 당신이 실제로하려고하는 것을 더 잘 이해하고 싶습니다. – markspace

+0

@markspace : SSE는 W3 표준의 잘 정의 된 주제입니다. OP : 코드가 제안하는대로 페이로드를 보내야합니다. – dandavis

+0

@dandavis는 표준 입력을 기다립니다. 그러나 페이로드 (예 : "data : hehehe \ n \ n"또는 기본적으로 system.in)를 보내면 브라우저가 연결을 종료해야합니다. 이것은 나를 괴롭히는 것입니다 .. –

답변

0

내 서버 헤더 문자열에 하나의 중요한 헤더가 누락되었습니다.

"Access-Control-Allow-Origin:*" + "\r\n" + ... 
관련 문제