2014-09-11 2 views
0

Мне нужно создать TCP-соединение в AppEngine (на стороне сервера) и поддерживать его на неопределенное время (или не менее ~ 30 минут). Я создал фоновый поток, открыл java.net.Socket и попытался прочитать строку с завернутым BufferedReader. Примерно через 3 секунды бездействия, я получаю следующее исключение:GAE Keep Socket Alive

java.net.SocketException: Socket operation timed out: The API call remote_socket.Receive() took too long to respond and was cancelled. 

Я включу скелет кода я использую ниже. Любая помощь будет с благодарностью (включая обходные пути или информацию об ограничениях сокетов в GAE). Благодаря!

ThreadFactory tm = ThreadManager.backgroundThreadFactory(); 
    thread = tm.newThread(new Runnable() { 
     @Override 
     public void run() { 
      Socket socket = null; 
      try { 
       socket = new Socket("localhost", 8000); 
       socket.setSoTimeout(0); 
       socket.setKeepAlive(true); 
       BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
       writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); 

       String in = reader.readLine(); 
       // execution never gets past here 
       //... 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } finally { 
       // ... <close socket> 
      } 
     } 
    }); 
    thread.start(); 

В случае, если это уместно, вот случай использования: У меня есть сервер TCP, который используется для работы со встроенным апплетом на стороне клиента. Я бы хотел перепроектировать Applet как webapp, но сервер все еще работает нормально, поэтому я не хочу его менять. Я хотел бы написать простой сервлет, который поддерживает соединение TCP и передает сообщения туда и обратно между сервером TCP и клиентом GWT.

+0

Это, вероятно, не будет работать. Каков ваш прецедент? Мы могли бы подумать об альтернативах с другими продуктами Google Cloud – Mario

+0

Я добавил описание - см. Последний абзац выше. – thomas88wp

ответ

1

Розетки имеет много ограничений в GAE из-за соображения безопасности, хотя GAE предоставляет множество готовых к использованию услуг, который требует использования сокетов как для электронной почты, XMPP и т.д..

Сначала ваше приложение должно быть платным приложением, означает, биллинг должен быть включен для использования сокетов на GAE

Вы можете иметь look here for how to use sockets in java on GAE

Ниже приведено отрывка из Google App Engine документации для сокета ограничения:

App Engine поддерживает сокеты, не требуя, чтобы импортировать любой специальный LIB App Engine raries или добавить какой-либо специальный код App Engine. Однако, есть определенные ограничения и поведение, которые Вы должны знать при использовании сокетов:

Sockets are available only for paid apps. 
You cannot create a listen socket; you can only create outbound sockets. 
java.net.URL is still configured to use the URL Fetch API; there is currently no way around this. 
Most classes in javax.net.ssl are supported. 
You can only use TCP or UDP; arbitrary protocols are not allowed. 
You cannot bind to specific IP addresses or ports. 
Port 25 (SMTP) is blocked; you can still use authenticated SMTP on the submission port 587. 
Private, broadcast, multicast, and Google IP ranges (except those whitelisted below), are blocked: 
    Google Public DNS: 8.8.8.8, 8.8.4.4, 2001:4860:4860::8888, 2001:4860:4860::8844 port 53 
    Gmail SMTPS: smtp.gmail.com port 465 and 587 
    Gmail POP3S: pop.gmail.com port 995 
    Gmail IMAPS: imap.gmail.com port 993 
Socket descriptors are associated with the App Engine app that created them and are non-transferable (cannot be used by other apps). 
Sockets may be reclaimed after 2 minutes of inactivity; any socket operation keeps the socket alive for a further 2 minutes. 
You cannot Select between multiple available sockets because that requires java.nio.SocketChannel which is not currently supported.) 
+0

Это в основном отвечает на мой вопрос. Код, который вы предоставляете, кажется, не предлагает способ преодоления тайм-аута 3s (заметьте, что я использую 'setSoTimeout()' '). Поправьте меня, если я пропустил это. – thomas88wp

+0

Я угадал, упустил его. В строке номера: 76 используется setSoTimeout (10000). Сокет будет блокироваться только в течение этого времени. Если истекает время ожидания, возникает исключение java.net.SocketTimeoutException, хотя Socket все еще действует. Опция должна быть активирована до того, как будет введена операция блокировки. Тайм-аут должен быть> 0. Тайм-аут нуля интерпретируется как бесконечный тайм-аут. – Akhil