Я написал сервер, который использует servicestack, и клиент, который подключается к нему с использованием как JSON, так и protobuf-net (поэтому я уверен, что сервер работает ...). Теперь мне нужно разработать тот же клиент на Windows Mobile с CF3.5, и поскольку servicestack не поддерживается на CF3.5, я использовал на клиенте HttpWebRequest и NewtonSoft.Json.Compact для json-части, таким образом:Protobuf-net с ServiceStack и компактным каркасом
Классы:
[ProtoContract]
public class ReqPing
{
}
[ProtoContract]
public class RespPing
{
[ProtoMember(1)]
public string Result { get; set; }
}
Функция:
ReqPing iReqPing = new ReqPing();
string json = JsonConvert.SerializeObject(iReqPing);
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://192.168.0.87:82/json/syncreply/ReqPing");
req.ContentType = "text/json";
req.Method = "POST";
req.ContentLength = json.Length;
using (var streamWriter = new StreamWriter(req.GetRequestStream()))
{
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Stream respStream = resp.GetResponseStream();
string resps;
using (var reader = new StreamReader(respStream, Encoding.UTF8))
{
resps = reader.ReadToEnd();
}
respStream.Close();
JsonTextReader jreader = new JsonTextReader(new StringReader(resps));
JsonSerializer serializer = new JsonSerializer();
RespPing iRespPing = serializer.Deserialize<RespPing>(jreader);
и это работает, так что теперь я пытаюсь реализовать то же самое с Protobuf, и я застрял здесь:
ReqPing iReqPing = new ReqPing();
var ms = new MemoryStream();?????? correct way?
Serializer.Serialize<ReqPing>(ms, iReqPing);
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://192.168.0.87:82/x-protobuf/reply/ReqPing");
req.ContentType = "application/x-protobuf";
req.Method = "POST";
req.ContentLength = ????????
how can I write the serialized stream to req??
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Stream respStream = resp.GetResponseStream();
RespPing iRespPing = Serializer.Deserialize<RespPing>(respStream);
Любой может предложить мне, как правильно?
Спасибо! Маттиа
EDIT:
Ok о том, как использовать этот поток, но мне нужно установить ContentLength также, или я получаю сообщение об ошибке на GetRequestStream (говорят, что я должен установить ContentLength ...). Я сделал это работать:
byte[] data;
using(var stream = new MemoryStream())
{
Serializer.Serialize(stream, iReqPing);
data = stream.ToArray();
req.ContentLength = data.Length;
}
using(var stream = req.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
Есть еще один очевидный способ, которым я не хватает?
Другой вопрос: Я заработал, но после двух запросов, на третьем таймаутах в GetRequestStream. Я заметил, что забыл в своем предыдущем звонке позвонить в Close() в свой HttpWebResponse, я исправил его и теперь работает. Странно то, что я забыл закрыть HttpWebResponse даже с моей версией JSON, и там у меня не было проблем ... рутина точно такая же .. можете ли вы угадать причину? Еще раз спасибо!
Я смущен - вы говорите о сериализации, но вызываете десериализацию. Вы пытаетесь прочитать здесь? Или написать? –
iReqPing - мой запрос, и я полагаю, что я должен Сериализовать его, чтобы отправить его с помощью HttpWebRequest. После этого я получаю поток ответов и пытаюсь десериализовать его в моем объекте ответа iRespPing. Я пытаюсь следовать той же схеме, которую я использовал для предыдущего примера JSON, bu хочет сериализоваться с protobuf вместо JSON. –