http-запрос Alamofire на локальный веб-сервер

Я разрабатываю приложение для iPhone, и план состоит в том, чтобы время от времени отправлять пакет JSON из приложения на локальный веб-сервер. Для этого я планировал использовать Alamofire. Мой метод POST выглядит так:

Alamofire.request(Alamofire.Method.POST, "http://XXX.XX.X.XX:3000/update", parameters: dictPoints, encoding: .JSON)
    .responseJSON {(request, response, JSON, error) in
    println(JSON)
}

IP-адрес выделен, но я убедился, что он соответствует беспроводному IPv4-адресу моего локального сервера. Сервер настроен на прослушивание порта 3000. Конфигурация сервера выглядит так:

var express = require('express');
var app = express();
var mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/test');

var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function (callback) {
  console.log("MongoDB connection is open.");
});

// Mongoose Schema definition
var Schema = mongoose.Schema;
var LocationSchema = new Schema({
    //some schema here
});

// Mongoose Model definition
var LocationsCollection = mongoose.model('locations', LocationSchema);

// URL management
app.get('/', function (req, res) {
    res.sendFile(__dirname + '/index.html');
});

app.get('/update', function (req, res) {
    console.log("Got something from the phone!");
});

// Start the server
var server = app.listen(3000, function () {
  var host = server.address().address
  var port = server.address().port
  console.log('App listening at %s:%s',host, port)
})

Итак, этот сервер, кажется, работает нормально. Я могу проверить это в своем браузере и ввести URL-адрес: http://127.0.0.1:3000, и он будет подавать мне файл index.html. Если я ввожу http://127.0.0.1:3000/update..., то получаю " Что-то с телефона!" сообщение. Однако, когда я запускаю свое приложение (убедившись, что мой телефон находится в той же беспроводной сети, что и сервер) и вызывается метод Alamofire... ответ, который я получаю, равен нулю. Я также не вижу сообщения "Получил что-то с телефона!" сообщение. Может ли кто-нибудь сообщить мне, почему это происходит ... или еще лучше, как это исправить?


person andyopayne    schedule 05.02.2015    source источник


Ответы (3)


Несколько мыслей:

  1. Вы создаете запрос POST в Alamofire, но сказали Express обрабатывать GET запросов для /update. Используйте app.post(...), если вы хотите обрабатывать его как POST.

  2. Ваш код Alamofire ищет ответ JSON, но вы, похоже, не создаете ответ JSON. В краткосрочной перспективе вы могли бы использовать responseString, а не responseJSON, но я предполагаю, что вы действительно хотите изменить свой веб-сервис, чтобы он отвечал с помощью JSON (чтобы приложению было проще анализировать ответы).

  3. Ваш код Alamofire отправляет запрос JSON (но ясно, что когда вы отправляете запрос через веб-браузер, это не JSON). Вы уверены, что хотите отправить запрос JSON? (Это не следует путать с проблемой ответа JSON.) Вы хотели использовать параметр типа кодирования .URL, а не .JSON?

  4. Всякий раз, когда у вас есть запрос, который правильно работает из веб-браузера, но не из приложения, полезно наблюдать за обоими с помощью такого инструмента, как Charles, и затем вы можете сравнить, чем они отличаются, и диагностировать источник различного поведения.

person Rob    schedule 05.02.2015
comment
Да. В идеале я отправлю правильный ответ, чтобы подтвердить, что пакет был обработан правильно... Но разве я не должен увидеть сообщение console.log, в котором говорится, что он получил что-то с телефона? Прямо сейчас я просто пытаюсь проверить, зарегистрировано ли сообщение, которое я отправляю с телефона, телефоном (после этого я могу разобрать сообщение и отправить правильный ответ). - person andyopayne; 06.02.2015
comment
Я изменил функцию Alamofire, чтобы использовать .responseString, а не .responseJSON, и сообщение, которое я получаю, выглядит следующим образом: Optional("Cannot POST /update\n"). Я также использовал Charles, когда делал это, и я не видел никакой активности в журнале (однако я видел запись, когда вводил IP-адрес в веб-браузер на своем компьютере). Знаете ли вы, что означает ответ Alamofire или почему он не будет отправлен по этому адресу? - person andyopayne; 06.02.2015
comment
@andyopayne Возможно, это ссылка app.get. Разве это не должно быть app.post, если вы хотите обрабатывать POST запросов для /update? - person Rob; 06.02.2015
comment
Что ж... это исправило сообщение "Cannot POST /update\n"... однако я все еще не получил сообщение "Got Something From the Phone!"... а также Чарльз, кажется, не сообщает о какой-либо активности http, когда телефон работает и отправляет пакеты JSON ( Я знаю это, потому что вижу, как возвращается reponseString). HTTP-запрос, похоже, никогда не доходит до веб-сервера... но, как я уже сказал... я могу ввести адрес веб-сервера в браузере (с портом), и он отлично работает. Какие-либо предложения? - person andyopayne; 06.02.2015
comment
На самом деле... Я не думаю, что что-то изменил в своем коде сервера (кроме изменения его на app.post), но теперь, похоже, он работает. Когда телефон звонит в Alamofire, я вижу, что с телефона что-то есть! сообщение в моей консоли. Так что, я думаю, теперь он работает как надо. Теперь перейдем к анализу сообщения JSON... но спасибо за помощь. - person andyopayne; 06.02.2015
comment
Кстати, что касается Чарльза, вы должны запустить его до запуска симулятора, и вы должны запустить приложение на симуляторе, чтобы Чарльз мог зафиксировать активность. - person Rob; 06.02.2015

Если вы используете сервер Express и симулятор iOS на одном компьютере, попробуйте использовать http://0.0.0.0:<port>/<url> вместо реального IP-адреса, в моем случае это помогло.

person Sergei Basharov    schedule 26.11.2015

Похоже, сервер узла не привязан к адресу, который вы ожидаете. Вы должны убедиться, что при вводе фактического IP-адреса в поле "http://XXX.XX.X.XX:3000/update" в веб-браузере, на который он отвечает. Детали вашего вопроса предполагают, что вы только что использовали петлевой адрес.

person JayL    schedule 06.02.2015
comment
Я действительно подтвердил, что когда я ввожу фактический адрес IPv4 с номером порта, он действительно обслуживает правильную страницу. Итак, я пробовал как 127.0.0.1:300, так и мой адрес IPv4: порт, и оба метода работают, как и ожидалось. Кроме того, я попытался использовать адрес IPv4 с портом из веб-браузера на другом компьютере (клиент и сервер находятся на разных компьютерах), и я могу заставить веб-сервер правильно обслуживать index.html. Итак, насколько я могу судить, эта часть работает правильно. - person andyopayne; 06.02.2015