/* Copyright (C) 2010 Copyright 2010 Google Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package com.googlecode.gwtquake.shared.client; import java.io.IOException; import java.net.InetAddress; import java.util.LinkedList; import com.google.gwt.corp.websocket.CloseEvent; import com.google.gwt.corp.websocket.MessageEvent; import com.google.gwt.corp.websocket.OpenEvent; import com.google.gwt.corp.websocket.WebSocket; import com.googlecode.gwtquake.shared.common.Compatibility; import com.googlecode.gwtquake.shared.common.NetworkAddress; import com.googlecode.gwtquake.shared.sys.QuakeSocket; import com.googlecode.gwtquake.shared.sys.QuakeSocketFactory; public class WebSocketFactoryImpl implements QuakeSocketFactory { public QuakeSocket bind(String ip, int port) { return new GwtWebSocketImpl(ip, port); } } class GwtWebSocketImpl implements QuakeSocket { private String ip; private WebSocket socket; private boolean connected; private LinkedList<String> msgQueue = new LinkedList<String>(); private int localPort; private int remotePort; private byte[] remoteIp; public GwtWebSocketImpl(String ip, int localPort) { this.ip = ip; this.localPort = localPort; System.out.println("Creating GwtWebSocketImpl(" + localPort + ")"); } public void close() throws IOException { System.out.println("closing"); if (socket != null) { socket.setListener(null); } if (connected) { socket.close(); connected = false; } socket = null; } public int receive(NetworkAddress address, byte[] buf) throws IOException { if (msgQueue.isEmpty()) { return -1; } String s = msgQueue.remove(); int len = Compatibility.stringToBytes(s, buf); // System.out.println("receiving: " + Lib.hexDump(buf, len, false)); address.ip = new byte[4]; System.arraycopy(remoteIp, 0, address.ip, 0, 4); address.port = remotePort; return len; } public void send(NetworkAddress adr, byte[] buf, int len) throws IOException { // TODO(haustein): check if addess still matches? if (socket == null) { remotePort = adr.port; remoteIp = new byte[4]; System.arraycopy(adr.ip, 0, remoteIp, 0, 4); String url = "ws://" + InetAddress.getByAddress(adr.ip).getHostAddress() + ":" + adr.port; System.out.println("connect for send to: " + url); socket = WebSocket.create(url, "" + localPort); System.out.println("socket: " + socket); socket.setListener(new WebSocket.Listener() { public void onOpen(WebSocket socket, OpenEvent event) { connected = true; } public void onMessage(WebSocket socket, MessageEvent event) { String data = event.getData(); msgQueue.add(data); } public void onClose(WebSocket socket, CloseEvent event) { connected = false; } }); } // System.out.println("sending: " + connected+ " " + Lib.hexDump(buf, len, false)); if (connected) { socket.send(Compatibility.bytesToString(buf, len)); } } }