Форум программистов, компьютерный форум CyberForum.ru

Веб-сервер и Android-устройства - Android

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 19, средняя оценка - 4.84
contedevel
 Аватар для contedevel
57 / 55 / 8
Регистрация: 07.10.2012
Сообщений: 589
14.04.2014, 13:39     Веб-сервер и Android-устройства #1
Здравствуйте!
Возникла необходимость разработать клиент-серверное приложение, в котором сервер - компьютер, доступный глобально, а клиент - это аппарат на Android OS. Но я раньше не занимался разработкой серверов, тем более для мобильных устройств и даже не знаю, что искать по этой теме.
У кого имеется опыт, прошу поделится...
Как тестировать подключение клиента на мобильнике к серверу на компьютере (если программа сервер запущена на компьютере, который не доступен глобально (локальный сервер)? В общем, как разрабатывать такие программы?
Пожалуйста, кто знает, ответьте... Любая информация по этой теме будет полезной!
Заранее спасибо!

Добавлено через 59 секунд
Я в этом пока не очень разбираюсь, поэтому если что-то не понятно, то поясню вопрос.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.04.2014, 13:39     Веб-сервер и Android-устройства
Посмотрите здесь:

Android Ошибка при запуске устройства из Android SDK Manager
Android + сервер Android
Android udid Android устройства
Выбор веб-сервиса с авторизацией для android клиента Android
Android Локальный сервер на Reddwarf и Android
Android Клиент-сервер для android
Android Android аппликация работаюшея с веб сервисом на .net(c#)
Клиент-сервер Linux-Android Android
Создание виртуального устройства Android Android
Android Устройства с Android ниже 4.0
Android Android, отправка фотографии на сервер
Android С андроид устройства на сервер в локальной сети

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
YuraAAA
 Аватар для YuraAAA
1563 / 1305 / 269
Регистрация: 25.10.2009
Сообщений: 3,424
Записей в блоге: 2
14.04.2014, 17:20     Веб-сервер и Android-устройства #2
Сообщение было отмечено автором темы, экспертом или модератором как ответ
contedevel, сейчас будем разбираться

Добавлено через 23 минуты
contedevel, для начала часть первая.
Самый примитивный сервер. Я в качестве платформы буду использовать Node JS (backend на основе javascript).

Генерим шаблонный проект на базе express 3.5. Покажу только значимые куски:



Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var express = require('express');
//+ остальные подключаемые модули
 
var app = express();
 
// используем 3000 порт
app.set('port', process.env.PORT || 3000);
//остальное
app.use(express.bodyParser());
 
 
 
//А вот и наши пути.
// /register - post запрос
// /info это будет get запрос.
app.post('/register', registration.authenticate);
app.get('/info', user.info);
 
//запускаем сервер.
http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});
Рассмотрим
app.post('/register', registration.authenticate);
app.get('/info', user.info);

Это значит, что у нас будет модуль registratiion с методом authenticate и user модуль с методом info.

Именно ЭТИ методы будут вызываться при получении запроса node'ой.

user.js
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * GET users listing.
 */
 
exports.info = function(req, res){
    var header = req.header('X-Auth'); //Ищем заголовок X-Auth
    if (!header || header !== 'secret_key') { //Если его нет или он не равен secret_key отвечаем, что фиг вам.
        res.json({
            err:{
                code:403,
                message:'Permission denied'
            }
        })
    } else {
        res.json({
            some_info:'Oh my god! We got it!' //А тут всё ок, юзер как бы настоящий
        })
    }
};
authenticate.js

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
exports.authenticate = function (req, res) {
    
    var name = req.body.name; //Ищем name
    if (!name) {
        res.json({
            code: 403
        });
        return;
    } else {
        var password = req.body.password; //Ищем пароль
        if (!password || password != 'secret') { //Если пароля нет или он не secret возвращаем 403
            res.json({
                code: 403
            });
            return;
        }
    }
    res.json({ 
        status:'success',
        token:'secret_key' //Иначе всё ок.
    });
};
Собственно, всё. Давайте проверять из консольки это дело. Запускаем сервер и тыкаем в него палкой.

Код
D:\untitled>curl localhost:3000/register
Cannot GET /register
всё верно. Регистрация - POST

D:\untitled>curl localhost:3000/register -X POST
{
"code": 403
}
и опять же, всё ок. Мы не передали нужные параметры (name, password)

D:\untitled>curl localhost:3000/register -X POST --data name=cyberforum --data password=secret
{
"status": "success",
"token": "secret_key"
}
вот и всё отлично. Мы передали нужные данные - получили ответ, что всё хорошо.


Теперь попробуем потыкать в info.

Код
D:\untitled>curl localhost:3000/info
{
  "err": {
    "code": 403,
    "message": "Permission denied"
  }
}
Всё верно, мы не передали секретный ключ в заголовке. Сервер нас не может распознать.

Код
D:\untitled>curl localhost:3000/info -H X-Auth:secret_key
{
  "some_info": "Oh my god! We got it!"
}
Вот теперь всё ок. Мы передали в хэдере "секретный" ключик и сервак нас понял.

С сервером всё. Сейчас будем смотреть клиент на Android.

Добавлено через 27 минут
Со стороны клиента нам надо выделить две составных части:

Сторона асинхронной работы с вебом и сторона UI.
Почему асинхронной - потому что по умолчанию андроид запускает один поток, отвечающий за отображение элементов. Все тяжеловесные операции должны выполняться в другом потоке.

+ нам надо вернуть результат как-то.

Значит будут составляющие:

Вызов задачи из asyncTask -> Выполнение задачи -> Генерирование ответа обратно через интерфейс обратного вызова (Callback).

Приступим. Механизм асинхронного вызова. Ничего сложного нет, наследуемся от AsyncTask. Используем generic для универсальности.

i
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
mport android.os.AsyncTask;
 
public abstract class MyIncredibleAsyncTask<T> extends AsyncTask<Void, Void, T> { //Используем типизацию
    private CallbackInterface<T> callbackInterface;
    private Throwable t; //Сигнал об ошибке
 
    public MyIncredibleAsyncTask(CallbackInterface<T> callbackInterface) {
        this.callbackInterface = callbackInterface;
    }
 
    @Override
    protected T doInBackground(Void... voids) {
        try {
            return doAction(); //Этот метод мы будем переопределять
        } catch (Throwable throwable) {
            t = throwable; //Что-то произошло
        }
        return null;
    }
 
 
    @Override
    protected void onPostExecute(T t) {
        super.onPostExecute(t);
        generateCallback(t); //Генерируем ответ
    }
 
    public abstract T doAction() throws Throwable;
 
 
    private void generateCallback(T data) {
        if (callbackInterface == null) return; //Не передали интерфейс, пока
        if (data != null) { //Всё ок, данные приехали
            callbackInterface.onSuccess(data);
        } else if (t != null) { //Что-то случилось (IOException и прочее)
            callbackInterface.onFailure(t);
        } else {
            callbackInterface.onError("Some shit happens"); //Не понятно. Нет ни ошибки, не результата.
        }
    }
 
}
и интерфейс:

Java
1
2
3
4
5
6
7
8
9
10
public interface CallbackInterface<T> {
 
    void onSuccess(T data);
 
    void onError(String serverError);
 
    void onFailure(Throwable t);
 
 
}
Теперь описываем Singleton-менеджер работы.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
 
import java.util.LinkedList;
import java.util.List;
 
public class DataManager {
    private HttpClient httpClient;
    private static DataManager instance;
 
 
    public static DataManager getInstance() {
        if (instance == null) {
            instance = new DataManager();
        }
        return instance;
    }
 
    private DataManager(){
        httpClient = new DefaultHttpClient();
    }
 
    public void authorization(final String name, final String pwd, CallbackInterface<String> callbackInterface) {
        new MyIncredibleAsyncTask<String>(callbackInterface) {
            @Override
            public String doAction() throws Throwable {
                HttpPost post = new HttpPost("http://10.0.2.2:3000/register"); //Вот ПОСТ запрос
                List<BasicNameValuePair> pairs = new LinkedList<BasicNameValuePair>();
                pairs.add(new BasicNameValuePair("name", name));
                pairs.add(new BasicNameValuePair("password", pwd));  //А это его "мясо"
                post.setEntity(new UrlEncodedFormEntity(pairs));
                HttpResponse execute = httpClient.execute(post);
                return EntityUtils.toString(execute.getEntity());
            }
        }.execute();
    }
 
    public void info(CallbackInterface<String> callbackInterface) {
        new MyIncredibleAsyncTask<String>(callbackInterface) {
            @Override
            public String doAction() throws Throwable {
                HttpGet get = new HttpGet("http://10.0.2.2:3000/info"); //Вот GET запрос
                get.setHeader(new BasicHeader("X-Auth", "secret_key")); //А это наш суперсекретный HEADER
                HttpResponse execute = httpClient.execute(get);
                return EntityUtils.toString(execute.getEntity());
            }
        }.execute();
    }
}
А вот и всё
Вызов:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class MyActivity extends Activity {
    public static final String TAG = DataManager.class.getSimpleName();
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        DataManager.getInstance().authorization("user", "password", new CallbackInterface<String>() {
 
            @Override
            public void onSuccess(String data) {
                Log.d(TAG, data);
                requestInfo();
            }
 
            @Override
            public void onError(String serverError) {
                Log.e(TAG, serverError);
            }
 
            @Override
            public void onFailure(Throwable t) {
                Log.e(TAG, t.getMessage(), t);
            }
        });
    }
 
    void requestInfo() {
        DataManager.getInstance().info(new CallbackInterface<String>() {
            @Override
            public void onSuccess(String data) {
                Log.d(TAG, data);
            }
 
            @Override
            public void onError(String serverError) {
                Log.e(TAG, serverError);
            }
 
            @Override
            public void onFailure(Throwable t) {
                Log.e(TAG, t.getMessage(), t);
            }
        });
    }
}
Вот логи:

авторизация:

Код
04-14 09:11:59.230      863-863/com.example.untitled2 D/DataManager﹕ {
    "code": 403
    }
всё верно. Я передал кривой пароль.

Код
04-14 09:11:59.650      863-863/com.example.untitled2 D/DataManager﹕ {
    "some_info": "Oh my god! We got it!"
    }
Правильный хэдер - всё окей.

Ну в принципе это всё. Это самый простой пример работы клиент-сервер.
contedevel
 Аватар для contedevel
57 / 55 / 8
Регистрация: 07.10.2012
Сообщений: 589
14.04.2014, 20:46  [ТС]     Веб-сервер и Android-устройства #3
Спасибо большое за подробный пример!
И еще нубский вопрос, а как проверить само подключение к серверу с Android-устройства? Просто у меня еще нет реального веб-сервера. Или это только через эмулятор подключаться?
YuraAAA
 Аватар для YuraAAA
1563 / 1305 / 269
Регистрация: 25.10.2009
Сообщений: 3,424
Записей в блоге: 2
15.04.2014, 12:19     Веб-сервер и Android-устройства #4
contedevel, вот этого я Вам не могу сказать. Знаю, что к веб серверу на локалхосте подключаться с эмулятора - 10.0.2.2, с реального девайса не знаю
contedevel
 Аватар для contedevel
57 / 55 / 8
Регистрация: 07.10.2012
Сообщений: 589
15.04.2014, 12:21  [ТС]     Веб-сервер и Android-устройства #5
Ну, хотя бы genymotion спасает тогда
Yandex
Объявления
15.04.2014, 12:21     Веб-сервер и Android-устройства
Ответ Создать тему
Опции темы

Текущее время: 22:56. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru