Windows Phone 7 client server implementation - windows-phone-7

I'm trying to create an application for windows phone 7 which acts as a client and which sends requests to a server which is written in Java. The client supposed to send a request, and wait for an answer from the server.
My problem is that I can't seem to communicate with the server properly. When I tried testing it in a simple .NET C# program and used blocking calls such as socket.send() and socket.receive() it works but the Windows Phone application doesn't have blocking calls.
This is what the server (Java) does once it detects a connection:
BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), "UTF-8"));
String message = reader.readLine();
PrintWriter writer = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream(), "UTF-8"));
writer.println("hiBack");
writer.close();
and this is how the client(C#) is implemented:
public void sendRequest()
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var connectionOperation = new SocketAsyncEventArgs { RemoteEndPoint = new DnsEndPoint(server, serverPort) };
connectionOperation.Completed += new EventHandler<SocketAsyncEventArgs>(onConnectCompleted);
socket.ConnectAsync(connectionOperation);
}
private void onConnectCompleted(object sender, SocketAsyncEventArgs e)
{
if (e.SocketError != SocketError.Success)
{
System.Console.WriteLine("Error! " + e.SocketError);
return;
}
var sendListener = new SocketAsyncEventArgs();
string msg = "hi";
var buffer = new System.Text.UTF8Encoding().GetBytes(msg + Environment.NewLine);
sendListener.SetBuffer(buffer, 0, buffer.Length);
sendListener = new SocketAsyncEventArgs { RemoteEndPoint = new DnsEndPoint(server, serverPort) };
sendListener.Completed += new EventHandler<SocketAsyncEventArgs>(onSendCompleted);
socket.SendToAsync(sendListener);
}
private void onSendCompleted(object sender, SocketAsyncEventArgs e)
{
socket.ReceiveAsync(e);
}
I've got a problem with the line: socket.SendToAsync(sendListener); on the C# side which end the program without doing anything (exit with return code 0).
the Java server starts it's work instantly when it detects the connection so it might also cause a problem?
What can I do to make the communication work?

Related

Sending Image with Exif info from Windows Phone to Java Server

I'm new in programming in Windows Phone (and StackOverflow tbh). Currently, I'm working on a task that concerns with sending images stored in the Windows Phone's storage (with Exif info) to a Java server. So far I have successfully send the byte stream from the Windows Phone client and construct the image on the Java side, however, the Exif information is somehow lost. I believe it's just the way I send it on Windows Phone that's causing the problem. Very much appreciated for any help or guidance !
Here's my code on the Windows Phone client:
// Windows Phone Client code (MainPage.xaml.cs)
// This function is called when an image is selected from
// the task PhotoChooserTask ptask, which brings
// a popup that allows the user to choose an image
// from the phone's storage
void ptask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK && e.ChosenPhoto != null)
{
//Take JPEG stream and decode into a WriteableBitmap object
App.CapturedImage = PictureDecoder.DecodeJpeg(e.ChosenPhoto);
// Attempt to send the image
WriteableBitmap pic = new WriteableBitmap(App.CapturedImage);
MemoryStream stream = new MemoryStream();
pic.SaveJpeg(stream, App.CapturedImage.PixelHeight, App.CapturedImage.PixelWidth, 0, 100);
stream.Seek(0, SeekOrigin.Begin);
client.Send(stream);
// Close the socket connection explicitly
client.Close();
}
}
Here's the code in the SocketClient.cs
public string Send(MemoryStream data)
{
byte[] msData = data.ToArray();
if (_socket != null)
{
// Create SocketAsyncEventArgs context object
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
// Set properties on context object
socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint;
socketEventArg.UserToken = null;
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
{
_clientDone.Set();
});
// Add the data to be sent into the buffer
socketEventArg.SetBuffer(msData, 0, msData.Length);
// Sets the state of the event to nonsignaled, causing threads to block
_clientDone.Reset();
// Make an asynchronous Send request over the socket
_socket.SendAsync(socketEventArg);
}
else
{
response = "Socket is not initialized";
}
return response;
}
On the Java Server,
public static void main(String[] args) {
ServerSocket serverSocket;
Socket client;
try {
serverSocket = new ServerSocket(PORT_NUMBER);
while (true) {
client = serverSocket.accept();
// Extract exif info
InputStream inputStream = client.getInputStream();
InputStream stream = new BufferedInputStream(inputStream);
// Create file from the inputStream
File file = new File("image.jpg");
try {
OutputStream os = new FileOutputStream(file);
byte[] buffer = new byte[4096];
for (int n; (n = stream.read(buffer)) != -1;) {
os.write(buffer, 0, n);
}
}
The output image is identical to the one sent from the windows phone, just without any Exif information whatsoever. Anyone could point out what I did wrong that causes the information to be lost? I'm guessing because I called the SaveJpeg function in the windows phone code, rewriting the image file, and losing all information there, but I don't know how else to convert the image to byte and stream it.
Much help is appreciated ! Thank you.
I found the answer to my own problem. For those of you who might have a problem with this. I simply use:
Byte[] imageData = new byte[e.ChosenPhoto.Length];
e.ChosenPhoto.Position = 0;
e.ChosenPhoto.Read(imageData, 0, imageData.Length);
Then send the byte array in my send function:
socketEventArg.SetBuffer(imageData, 0, imageData.Length);

DownloadStringCompleted event does not fire

I am developing a windows phone application. The webclient does not fire as I expected. The related code is as below:
public PArticle(PocketListItem aPli)
{
this.pli = aPli;
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!isf.FileExists(aPli.ID + ".json"))
{
WebClient client = new WebClient();
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
client.DownloadStringAsync(new Uri(pli.Url));
}
else
{
string json = RetrieveDataFromLocalStorage(aPli.ID + ".json");
PocketArticle pa = JsonConvert.DeserializeObject<PocketArticle>(json);
this.text = pa.text;
}
}
}
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
var readability = Readability.Create(e.Result);
this.text = readability.Content;
}
I know it's a synchronous/asynchronous problem. But I have no idea about how to handle it.
Thanks in advance.
I have tested the WebClient part of your code with 2 different URLs http://riktamtech.com and http://google.com. In both cases, the DownloadStringCompleted event is raised. I observed it by placing a break point.
So I suggest you to test again with break points.

WebClient wait operation - Windows Phone 7

I've read that the communications are asynchronous WP7 but there are cases that do not lack this type of communication.
I am using webclient to download content and just want to go to the next operation, after receiving such content.
How is this done?
I'm a noob on this platform.
Cumpz
It sounds like you are looking for a synchronous method. If that is the case, you can do something like this:
AutoResetEvent waitHandle = new AutoResetEvent(false);
WebRequest request = WebRequest.Create(url) as HttpWebRequest;
IAsyncResult asyncResult = request.BeginGetResponse(ar => waitHandle.Set(), null);
if (!waitHandle.WaitOne(30000))
{
throw new TimeoutException("Timed out");
}
using (HttpWebResponse response = request.EndGetResponse(asyncResult) as HttpWebResponse)
{
...
Here is some code which will help you get started using the WebClient class
Create the WebClient
WebClient client = new WebClient())
client.DownloadStringAsync(new Uri("http://www.google.com"));
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
Now, do something once the download string operation has finished
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
string result = e.Result;
// Do something with the string
DoThingWithString(result)
}

when try to download a mp3 ;an error occur "The remote server returned an error: NotFound."

when i down load the two same link like those
a link! and http://files.sparklingclient.com/099_2010.07.09_WP7_Phones_In_The_Wild.mp3
they all can be downloded by IE .but when i download in wp7 the laster can be downloaded the first show an error ""The remote server returned an error: NotFound.""
i don't konw why .is webURL is not suited for wp7?
private void Button_Click(object sender, RoutedEventArgs e)
{
stringUri = "http://upload16.music.qzone.soso.com/30828161.mp3";
//stringUri = "http://files.sparklingclient.com/079_2009.08.20_ElementBinding.mp3";
Uri uri = new Uri(stringUri, UriKind.Absolute);
GetMusic(uri);
}
private void GetMusic(Uri uri)
{
request = WebRequest.Create(uri) as HttpWebRequest;
request.Method = "Post";
request.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
string header= request.Accept;
request.BeginGetResponse(new AsyncCallback(GetAsynResult),request);
}
void GetAsynResult(IAsyncResult result)
{
HttpWebResponse reponse = request.EndGetResponse(result) as HttpWebResponse;
if (reponse.StatusCode == HttpStatusCode.OK)
{
Stream stream=reponse.GetResponseStream();
SaveMusic(stream, "music");
ReadMusic("music");
Deployment.Current.Dispatcher.BeginInvoke(
() =>
{
me.AutoPlay = true;
me.Volume = 100;
songStream.Position = 0;
me.SetSource(songStream);
me.Play();
});
}
}
protected void SaveMusic(Stream stream,string name)
{
IsolatedStorageFile fileStorage = IsolatedStorageFile.GetUserStoreForApplication();
if (!fileStorage.DirectoryExists("Source/Music"))
{
fileStorage.CreateDirectory("Source/Music");
}
using (IsolatedStorageFileStream fileStream = IsolatedStorageFile.GetUserStoreForApplication().OpenFile("Source\\Music\\" + name + ".mp3", FileMode.Create))
{
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
fileStream.Write(bytes, 0, bytes.Length);
fileStream.Flush();
}
}
protected void ReadMusic(string name)
{
using (IsolatedStorageFile fileStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
songStream = null;
songStream = new IsolatedStorageFileStream("Source\\Music\\" + name + ".mp3", FileMode.Open, fileStorage);
}
}
Please try to change
request.Method = "Post"
to
request.Method = "Get"
If you are running into this problem on the emulator, have you tried running Fiddler? It will intercept the HTTP requests and you can see if the call being made to the server is the one you expect.
Remember to close/reopen the emulator after you start Fiddler so that it will pick up the proxy.
The NotFound response can also occur with bad SSL certificates. That doesn't appear to be related to your problem, but something to keep in mind.

WP7 WebClient DownloadStringAsync and Map

I'm using WebClient object in to poll some data from server.
It's working good and it's updating text block fine. Till I don't use map on same Page. When I add a map, only one request get completed and data is retrieved only once.
This is the code for getting messages:
public MessagesPage()
{
InitializeComponent();
new System.Threading.Timer(messagePolling, null, 0, 5000); // every 5 seconds
}
void messagePolling(object state)
{
getMessages(Const.GET_MESSAGES_URL + uuid);
}
private void getMessages(string uri)
{
WebClient webClient = new WebClient();
webClient.DownloadStringAsync(new Uri(uri));
webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(messagesResponseCompleted);
}
void messagesResponseCompleted(object sender, DownloadStringCompletedEventArgs e)
{
lock (this)
{
try
{
string s = e.Result;
if (s.Length > 0)
{
List<Message> messagesResult = JSONHelper.Deserialize<List<Message>>(s);
foreach (Message m in messagesResult)
{
tbMessages.Text += m.message + "\n";
}
}
else
{
tbMessages.Text += "No new messages #: " + System.DateTime.Now + "\n";
}
}
catch (System.Net.WebException we)
{
MessageBox.Show(we.Message);
}
}
}
Anyone?
The WebClient response is processed on the UI thread - so you don't need the lock that you have in your event handler.
For your particular problem - is this just occurring in the emulator? I've seen quite a few timer issues with the emulator - but never anything similar on the real phone.
As an aside, I believe in general it's better to use HttpWebRequest rather than WebClient - see the explanation here of webclient using the UI thread Silverlight Background Thread using WebClient - for your particular code I don't think this will be a problem.
If using
System.Windows.Threading.DispatcherTimer myDispatcherTimer = new System.Windows.Threading.DispatcherTimer();
myDispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 5000);
myDispatcherTimer.Tick += new EventHandler(messagePolling);
myDispatcherTimer.Start();
instead of
new System.Threading.Timer(messagePolling, null, 0, 5000); // every 5 seconds
is working fine =)

Resources