2012-06-11 1 views
0

2 개의 스레드가있는 루비 프로그램을 작성하고 있습니다. 하나는 들어오는 UDP 연결을 듣고 다른 하나는 클라이언트 쪽의 브라우저가 읽은 websocket에서 브로드 캐스트합니다. em-websocket gem을 사용하고 있습니다. 그러나 내 UDP 리스너 스레드는 결코 호출되지 않고 코드가 websocket 초기화 코드 내에있는 것처럼 보입니다. em-websocket이 (가) 차단되어 있기 때문에 추측하고 있지만, 제안하는 정보를 온라인에서 찾을 수 없었습니다. 그것은 내 편이 잘못입니까? 저는 루비를 처음 접했기 때문에 내가 뭘 잘못하고 있는지 알 수 없습니다.은 Ruby em-websocket 차단입니까?

require 'json' 
require 'em-websocket' 
require 'socket' 

socket=nil 
text="default" 
$x=0 

EventMachine.run do 
EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 8080) do |ws| 
    ws.onopen { 
      ws.send "Hello Client!" 
      socket=ws 
      $x=1 
     } 

    ws.onmessage { |msg| socket.send "Pong: #{msg}" } 
    ws.onclose { puts "WebSocket closed" } 
end 
end 
def listen() 
puts "listening..." 
s = UDPSocket.new 
s.bind(nil, 3000) 
while 1<2 do 
    text, sender = s.recvfrom(1024)  
    puts text 
    if $x==1 then 
    socket.send text  
    end 
end 
end 

t2=Thread.new{listen()} 
t2.join 

답변

4

em-websocket 그러나 UDPSocket#recv_from이고, 비 차단된다. 대신 EventMachine의 open_datagram_socket을 사용하는 것이 좋습니다.

참고 사항 : socket을 "전역"변수로 표시해서는 안됩니다. 누군가가 이전에 연결된 클라이언트에 대한 참조를 연결할 때마다 손실됩니다. 어쩌면 소켓 연결을위한 일종의 저장소를 만들거나 뭔가가 들어올 때 메시지를 브로드 캐스팅하기 위해 옵저버 패턴을 사용할 수 있습니다. 내가 할 수있는 것은 거짓 개체가 관찰자 역할을하고 소켓이 연결될 때/등록을 끊을 때 /에서 등록을 해제 할 때입니다. 관찰자 :

require 'observer' 

class Dummy 
    include Observable 

    def receive_data data 
    changed true 
    notify_observers data 
    end 
end 

# ... later on ... 

$broadcaster = Dummy.new 

class UDPHandler < EventMachine::Connection 
    def receive_data data 
    $broadcaster.receive_data data 
    end 
end 

EventMachine.run do 
    EM.open_datagram_socket "0.0.0.0", 3000, UDPHandler 

    EM::WebSocket.start :host => "0.0.0.0", :port => 8080 do |ws| 
    ws.onopen do 
     $broadcaster.add_observer ws 
    end 

    ws.onclose do 
     $broadcaster.delete_observer ws 
    end 

    # ... 
    end 
end 

EventMachine의 요점은 멀리 기본 소켓 및 스레딩 구조에서 추상적이고, 내부적으로 모든 비동기 비트를 처리 할 수 ​​있습니다. UDPSocket 또는 Thread과 같은 클래식 라이브러리를 EventMachine과 섞어 놓지 않는 것이 가장 좋습니다.

+0

답장을 보내 주셔서 감사합니다! 내 websocket send 호출이 차단되어 있고 "socket = ws"문 때문이라고 추측합니다. 나는 관찰자가 무엇인지 정확히 모르겠다. 그러나 나는 그것을 관찰하고 그것을 사용하려고 노력할 것이다. 감사! – InfiniteLoop

+0

메소드에서 websocket을 초기화 할 때 다른 핸들에서 소켓 핸들을 사용하려면 어떻게해야합니까? 참조 범위는 전 세계적으로 확장되지 않는 것 같습니다. 왜 그래도 모르겠다. 자바/C와 비교할 때 루비의 범위가 다른가요? – InfiniteLoop

+0

괜찮습니다. 나는 그 문제를 알아 냈다. 변수 소켓을 '$'기호로 정의하지 않았습니다. 그래서 그것은 전 세계적 범위에 있지 않았습니다. 나는 루비의 범위 차이에 대해 몰랐다. 어쨌든 당신의 도움에 감사드립니다! – InfiniteLoop