2012-06-26 2 views
2

Привет Я новичок в таких вещах, но вот что я хочу сделать.Socket php server не отображает сообщения, отправленные от клиента android

Я пытаюсь внедрить приложение чата, в котором пользователи будут отправлять свои запросы с веб-сайта и как только сообщения будут отправлены пользователями сайта. Он появится в приложении для Android от владельца сайта, который ответит их запросы. Короче говоря, я хочу реализовать живой чат.

Теперь прямо сейчас я просто пытаюсь отправить сообщения из приложения android на php-сервер. Но когда я запускаю свой php-скрипт из Dreamweaver в Chrome, браузер продолжает загружаться и не показывает никакого вывода, когда я отправляю сообщение от клиента.

Иногда случалось, что скрипт php показал некоторые выходные данные, которые я отправил с андроида (клиентом). Но я не знаю, когда он работает, а когда нет.

Так что я хочу показать эти сообщения в php-скрипте, как только я отправлю эти сообщения от клиента, и наоборот (не был реализован наоборот для клиента, но помощь будет оценена).

Вот что я сделал до сих пор.

PHP скрипт:

<?php 

set_time_limit (0); 
$address = '127.0.0.1'; 

$port = 1234; 

$sock = socket_create(AF_INET, SOCK_STREAM, 0); 
socket_bind($sock, $address, $port) or die('Could not bind to address'); 
socket_listen($sock); 


$client = socket_accept($sock); 
$welcome = "Roll up, roll up, to the greatest show on earth!\n? "; 
socket_write($client, $welcome,strlen($welcome)) or die("Could not send connect string\n"); 

do{ 
$input=socket_read($client,1024,1) or die("Could not read input\n"); 
echo "User Says: \n\t\t\t".$input; 

if (trim($input) != "") 
    { 
    echo "Received input: $input\n"; 
    if(trim($input)=="END") 
    { 
     socket_close($spawn); 
     break; 
    } 
} 
else{ 

$output = strrev($input) . "\n"; 
socket_write($spawn, $output . "? ", strlen (($output)+2)) or die("Could not write output\n");    
echo "Sent output: " . trim($output) . "\n"; 

} 
} 
while(true); 


socket_close($sock); 
echo "Socket Terminated"; 
?> 

Android Код:

public class ServerClientActivity extends Activity { 
    private Button bt; 
    private TextView tv; 
    private Socket socket; 
    private String serverIpAddress = "127.0.0.1"; 

    private static final int REDIRECTED_SERVERPORT = 1234; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    bt = (Button) findViewById(R.id.myButton); 
    tv = (TextView) findViewById(R.id.myTextView); 

    try 
    { 
     InetAddress serverAddr = InetAddress.getByName(serverIpAddress); 
     socket = new Socket(serverAddr, REDIRECTED_SERVERPORT); 
    } 
    catch (UnknownHostException e1) 
    { 
     e1.printStackTrace(); 
    } 
    catch (IOException e1) 
    { 
     e1.printStackTrace(); 
    } 


    bt.setOnClickListener(new OnClickListener() { 
     public void onClick(View v) { 
      try 
      { 
       EditText et = (EditText) findViewById(R.id.EditText01); 
       String str = et.getText().toString(); 
       PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true); 
       out.println(str); 
       Log.d("Client", "Client sent message"); 
      } 
      catch (UnknownHostException e) 
      { 
       tv.setText(e.getMessage()); 
       e.printStackTrace(); 
      } 
      catch (IOException e) 
      { 
       tv.setText(e.getMessage()); 
       e.printStackTrace(); 
      } 
      catch (Exception e) 
      { 
       tv.setText(e.getMessage()); 
       e.printStackTrace(); 
      } 
     } 

    });  

    } 
} 

Я только что вставили кнопки OnClick код события для Android.Edit текста в текстовом поле, куда я иду, чтобы ввести свой текст , IP-адрес и порт такие же, как в php-скрипте.

+0

Это может быть немного не по теме, вы могли бы получить вдохновение и полезные советы здесь, в моем предыдущем посте. https://stackoverflow.com/questions/29159354/php-socket-with-android/45851814#45851814 И вот загрузка к очень полезному коду, который может вам помочь. http://developersfound.com/PHP_SocketServer_Android_SocketClient.zip – user2288580

ответ

1

Я бы рекомендовал использовать фреймворк, управляемый событиями для обработки ваших соединений.

Существует довольно приличный пример, называемый React, но в нем есть много других вещей, которые вы, вероятно, захотите снять, чтобы ваше приложение не зависело от сотен внешних компонентов.

React использует контур сообщения на основе libevent, если он у вас установлен, или stream_select в противном случае.

обрабатывать события с закрытием, что-то вроде:

$client->on('read', function($data) use ($client) { 
     $client->onRead($data); 
    }); 

С этим вы будете иметь возможность обрабатывать большое количество одновременных соединений, и он не будет связать все ваши CPU.

Ваш код будет выполнен , когда что-то происходит.

Если ничего более, взгляните на то, как это работает, вы получите лучшее представление о том, как создать несекретный сервер сокетов, управляемый событиями.

1

Прежде всего - ваш сервер будет обрабатывать только одно соединение с клиентом за раз, что не имеет смысла для чата.

Я не вижу, как вы имеете дело с подключением сокетов на стороне Android, но в любом случае он не позволит вам подключаться снова, пока выполнение вашего сценария не будет выполнено «socket_accept()» и дождитесь соединения.

Вы должны запустить 1 цикл, чтобы захватить новые клиентские соединения и вилку в отдельный процесс каждого подключенного клиента.

Примите взгляд на мой же легкий PHP сервер я написал здесь, который основан на том же принципе: https://github.com/webdevbyjoss/Aaaaa---space-ships-combat-multiplayer-game/blob/master/server/server.php

Игнорируйте WebSockets, связанные «doHandshake()» и "WebSocketFrame :: расшифровывает/WebSocketFrame: : encode «но с тобой все в порядке.

Обычно он работает Петля

while (true) 

    if (($msgsock = socket_accept ($sock)) === false) { 
     echo "socket_accept() failed: reason: " . socket_strerror (socket_last_error ($sock)) . "\n"; 
    break; 
    } 

    // We got a client connected, lets process it in separate thread 
    if (($pid = pcntl_fork()) === -1) { 
     echo "pcntl_fork() failed. Make sure you are on Linux sustem, but not on Windows\n"; 
     break; 
    } 

    if (!$pid) { // client 
     handleClient($msgsock); 
     exit(); 
    } 

    // parent server will wait to accept more clients connections in new loop 
} 

А внутри handleClient() функции вы должны иметь отдельный контур для общения с клиентом.

while (true) { 
    if (false === ($buf = socket_read ($msgsock, 2048, PHP_BINARY_READ))) { 
     echo "socket_read() failed: reason: " . socket_strerror (socket_last_error ($msgsock)) . "\n"; 
     return; 
    } 

    if (empty($buf)) { // do disconnection check 
     echo "Client disconnected\n"; 
     return; 
    } 

    // ------------------------------------------------------------- 
    // PUT YOUR BUSINESS LOGIC HERE 
    // TO HANDLE MESSAGES OF THE CHAT AND GENERATE RESPONSE TO USER 
    // I RECOMMEND TO USE SOMETHING LIKE MEMCACHE/REDIS/MONGO/MYSQL/TXT-FILES 
    // FOR MULTIPROCESS DATA INTERCHANGE 
    // ------------------------------------------------------------- 

// transfer data to client 
    socket_write($msgsock, $returnText, strlen($returnFrame)); 
} 

socket_close ($msgsock); 
+0

thnx для ответа Я использую Windows. Так что это имеет значение, поскольку вы написали код, который должен использовать linux? – Mj1992

+0

та же проблема связана с тем, что страница продолжает загружаться, и когда я отправляю сообщения от клиента android, он ничего не делает, просто продолжает загружать страницу. Я обновил код Android. – Mj1992

+1

'stream_select'>' pcntl_fork'. Время изучать программирование, управляемое событиями. – Leigh

0

Вы пытались добавить '\ r \ n' в значение EditText перед отправкой на сервер?Я думаю, что проблема заключается не в связи между клиентом и сервером, потому что при сбое соединения не появляется ошибка.
Возможно, в вашем случае socket_read ($ client, 1024,1) должен прекратить чтение с '\ r \ n'.

Обновление: Ваш локальный ip может вызвать ошибку подключения. Посмотрите на this link

+0

не работает :) – Mj1992

+0

@ Mj1992: Я обновил свой ответ. Вы должны записывать журнал при сбое соединения и обновлять свой вопрос с помощью logcat, особенно при создании нового сокета на стороне android. – R4j

0

Ваш адрес 127.0.0.1 разрешит машине, на которой работает код. Поэтому приложение действительно пытается подключиться к самому себе. введите ipconfig /all на консоли MSDOS и вместо этого используйте этот адрес.

Смежные вопросы