message being consumed even if the consumer is down RabbitMQ - c#

I am writing async communication between services so if one goes down the request can't be stopped
so I am doing this scenario
I am turning off my consumer and sending message through the producer
I get a response that the message has been sent successfully
but when I run my consumer on again no message in the queue
Note :
when I don't turn off my consumer i can get my message and consume it
this is my producer code
var factory = new ConnectionFactory() { HostName = "host.docker.internal" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.ExchangeDeclare(exchange: "UserRequestExch", type: ExchangeType.Direct);
UserInfo userInfo = new UserInfo();
userInfo.UserID = GetCurrentUserID();
userInfo.JWT=GetCurrentUserToken();
var mess = System.Text.Json.JsonSerializer.Serialize(userInfo);
var body = Encoding.UTF8.GetBytes(mess);
string RoueKey = "";
switch (Int32.Parse(dataObject["PostponementID"].ToString()))
{
case 1:
RoueKey = "AlonePostponement";
break;
case 2:
RoueKey = "BrotherInServicePostponement";
break;
case 3:
RoueKey = "CashAllowance";
break;
case 4:
RoueKey = "CashAllowancLessThan42";
break;
case 5:
RoueKey = "FixedServiceAllowance";
break;
case 6:
RoueKey = "ObligatoryService";
break;
case 7:
RoueKey = "PostponementOfConvicts";
break;
case 8:
RoueKey = "SchoolPostponement";
break;
case 9:
RoueKey = "TravelApproval";
break;
default:
return NotFound();
}
channel.BasicPublish("UserRequestExch", RoueKey, null, body);
return Ok("The request has been received and is now being processed");
my consumer code :
factory = new ConnectionFactory() { HostName = "host.docker.internal" };
connection = factory.CreateConnection();
channel = connection.CreateModel();
channel.ExchangeDeclare(exchange: "UserRequestExch", ExchangeType.Direct);
var queName = channel.QueueDeclare().QueueName;
channel.QueueBind(queue: queName, exchange: "UserRequestExch", routingKey: "TravelApproval");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var recbody = ea.Body.ToArray();
var recmess = Encoding.UTF8.GetString(recbody);
UserInfo userInfo = JsonSerializer.Deserialize<UserInfo>(recmess);
var User = _context.TravelApprovalDb.Where(x => x.UserID == userInfo.UserID).FirstOrDefault();
if (User == null)
{
int ReqStatuesID = InsertRequestToDB(userInfo.UserID);
SendToExternalAPI(userInfo.JWT, ReqStatuesID);
}
else
{
if (User.DateOfEnd.DateTime > DateTime.Now)
{
int ReqStatuesID = InsertRequestToDB(userInfo.UserID);
SendToExternalAPI(userInfo.JWT, ReqStatuesID);
}
}
channel.BasicAck(deliveryTag:ea.DeliveryTag,multiple:true);
};
channel.BasicConsume(queue: queName, consumer: consumer);
System.Console.Read();
I have applied persistent volume to the rappitMQ in docker-compose
volumes:
- rabbitmq:/var/lib/rabbitmq
or
- ~/.docker-conf/rabbitmq/data/:/var/lib/rabbitmq/
- ~/.docker-conf/rabbitmq/log/:/var/log/rabbitmq
I removed auto ack and put
channel.BasicAck(deliveryTag:ea.DeliveryTag,multiple:true);
but nothing happened

Related

api controller using AspNetCore.Reporting thows System.FormatException: 'The header contains invalid values at index 0

This api controller is used to return a pdf stream to display in an html object tag
using AspNetCore.Reporting;
using Microsoft.AspNetCore.Mvc;
[HttpGet, Route("ProcedureRangeForm")]
public IActionResult ProcedureRangeForm(string procedureRangeId, byte procedureTypeId)
{
int extension = 1;
var _reportPath = "";
switch (procedureRangeId)
{
case "1":
_reportPath = #"Reports\ProcedureRangeForm1.rdlc";
break;
case "2":
_reportPath = #"Reports\ProcedureRangeForm2.rdlc";
break;
case "3":
_reportPath = #"Reports\ProcedureRangeForm3.rdlc";
break;
default:
// code block
break;
}
//Employee employee = _context.Employees.FirstOrDefault(x => x.Id == "41")!;
ProcedureType procedureType = _context.ProcedureTypes.FirstOrDefault(x => x.Id == procedureTypeId);
//RelationDegree relationDegree = _context.RelationDegrees.FirstOrDefault(x => x.Id == 1)!;
var reportParams1 = new Dictionary<string, string>();
var reportParams2 = new Dictionary<string, string>();
var reportParams3 = new Dictionary<string, string>();
reportParams1.Add("UnitCode", "UnitCode");
reportParams1.Add("ProcedureType", procedureType!.Name!);
reportParams2.Add("ProcedureType", procedureType!.Name!);
reportParams3.Add("ProcedureType", procedureType!.Name!);
//reportParams1.Add("Attachments", "");
LocalReport localReport = new LocalReport(_reportPath);
FileContentResult fileContentResult;
MemoryStream memory = new();
try
{
ReportResult result = null!;
switch (procedureRangeId)
{
case "1":
result = localReport.Execute(RenderType.Pdf, extension, parameters: reportParams1);
break;
case "2":
result = localReport.Execute(RenderType.Pdf, extension, parameters: reportParams2);
break;
case "3":
result = localReport.Execute(RenderType.Pdf, extension, parameters: reportParams3);
break;
default:
// code block
break;
}
byte[] file = result.MainStream;
fileContentResult = new FileContentResult(file, "application/pdf");
}
catch (Exception e)
{
Console.WriteLine("{0} Exception caught.", e);
return Content(HttpStatusCode.InternalServerError.ToString(), e.Message);
}
finally
{
}
return fileContentResult;
}
I want to call this api more than once with varient parameters. when i call once to display ProcedureRangeForm1.rdlc it run successfully , but when i call again to display ProcedureRangeForm2.rdlc throw this exception
System.FormatException: 'The header contains invalid values at index 0: 'An error occurred during local report processing.;The definition of the report 'Reports\ProcedureRangeForm1.rdl' is invalid. An unexpected error occurred in Report Processing. The process cannot access the file 'hdsktzjh.err' because it is being used by another process.''
After a lot of research, I found a solution to my question:
First, I used nuget package Tmds.ExecFunction by Execute a function in a separate process
as in this link
But I didn't get what I wanted
And then I replaced the library AspNetCore.Reporting by ReportViewerCore.NETCore
as in this link
the problem solved as this code
using Microsoft.Reporting.NETCore;
[Route("api/[controller]")]
[ApiController]
public class ProcedureRangeFormsController : ControllerBase
{
private readonly HousingDbContext _context;
public ProcedureRangeFormsController(HousingDbContext context)
{
_context = context;
}
// GET api/values
[HttpGet, Route("ProcedureRangeForm/{procedureRangeId}/{procedureTypeId}")]
public IActionResult ProcedureRangeForm(string procedureRangeId, string procedureTypeId)
{
var reportPath = "";
switch (procedureRangeId)
{
case "1":
reportPath = "TaxHousing.Reports.ProcedureRangeForm1.rdlc";
break;
case "2":
reportPath = "TaxHousing.Reports.ProcedureRangeForm2.rdlc";
break;
case "3":
reportPath = "TaxHousing.Reports.ProcedureRangeForm3.rdlc";
break;
default:
// code block
break;
}
using var rs = Assembly.GetExecutingAssembly().GetManifestResourceStream(reportPath);
var localReport = new Microsoft.Reporting.NETCore.LocalReport();
localReport.LoadReportDefinition(rs);
var reportParams1 = new[] {
new ReportParameter("ProcedureType", "ProcedureType1"),
new ReportParameter("UnitCode", "UnitCode1")
};
var reportParams2 = new[] {
new ReportParameter("ProcedureType", "ProcedureType2")
};
var reportParams3 = new[] {
new ReportParameter("ProcedureType", "ProcedureType3")
};
byte[] file = null;
switch (procedureRangeId)
{
case "1":
localReport.SetParameters(reportParams1);
break;
case "2":
localReport.SetParameters(reportParams2);
break;
case "3":
localReport.SetParameters(reportParams3);
break;
default:
// code block
break;
}
try
{
file = localReport.Render("PDF");
}
catch (Exception e)
{
Console.WriteLine("{0} Exception caught.", e);
return Content(HttpStatusCode.InternalServerError.ToString(), e.Message);
}
return new FileContentResult(file, "application/pdf");
}
}

WNS pushnotification only sending to some tags

Outline
I am trying to implement WNS for my app game. I currently send a notification upon creation of a new user with the following function which works:
public async void SendNotificationToTag(string tag, string content)
{
var wnsToast = "<toast><visual><binding template=\"ToastText01\">"
+ "<text id=\"1\">Breaking " +content + "An WNS News!"
+ "</text></binding></visual></toast>";
WindowsPushMessage wnsMessage = new WindowsPushMessage();
wnsMessage.XmlPayload = wnsToast;
await Services.Push.HubClient.SendWindowsNativeNotificationAsync(wnsToast, tag);
Services.Log.Info("WNS TEST - SendWindowsNativeNotificationAsync - done");
}
I get a notfication to each username, i.e. a personal notificaion. I then update the tags the user listens to, looking in the hub database this also seems to work:
-Usernamecph--gameID1151--gameID1152--gameID1153--gameID1154--gameID1155--gameID1156--gameID1157--gameID1158
-gameID1157--UsernameFyn--gameID1151--gameID1153--gameID1155--gameID1156-
This check to extract the tags from the hub is done using
foreach (Microsoft.ServiceBus.Notifications.RegistrationDescription t in a)
{
string tempstring = "";
foreach (string x in t.Tags)
tempstring += "-" + x + "-";
Services.Log.Info(tempstring + t.RegistrationId + t.ETag);
}
So far so good.
When I then try to send to one of the other tags than the usernames I do not receive any notification, and I do not receive any error in the log. Am I missing something?
Update - Half Solution
If I use the server Explorer and look at the notification HUB. I can see all the tags, and I can send to them by using the test send. But I cannot seem to do it in other function calls online.
Is it something like the function has to be set as post or get?
YES
So inserting [HttpPost] Seems to enable the push.
However when I look in the Server explorer shown here on the image:
The user seems to be deleted when I update the registrations (There should be three, and there is again when I start the app with the correct tag subscriptions). So Maybe the question is How to Update a registration in the hub correctly
The current update code:
public async void updateRegistration(RegistrationDescription registration, List<string> TAGS)
{
registration.Tags = new HashSet<string>(TAGS);
try
{
var x = await hub.CreateOrUpdateRegistrationAsync(registration);
// apiServices.Log.Info(x.ExpirationTime + " " + x.Tags);
}
catch (MessagingException e)
{
ReturnGoneIfHubResponseIsGone(e);
}
}
The code that calls the function:
private async Task<bool> RegisterHubTag(User user, string Tag)
{
List<string> sendTAGs = new List<string>();
Services.Log.Info("RegisterHubTag Function");
using (Db db = new Db())
{
List<DataObjects.NotificationTag> userTags = db.NotificationTags.Where(t => t.User.UserId == user.UserId).ToList<DataObjects.NotificationTag>();
if (userTags.Count < 1)
{
//Register
RegisterController.DeviceRegistration Reg = CreateDeviceRegistration(user.PushChannelUri, sendTAGs);
Microsoft.Azure.NotificationHubs.RegistrationDescription registration = null;
//Microsoft.ServiceBus.Notifications.RegistrationDescription registration = null;
Services.Log.Info(Reg.Handle);
Services.Log.Info(Reg.Platform);
IEnumerable<string> tagsToRegister;
List<string> test = new List<string>() { user.Username };
if(Tag != user.Username)
test.Add(Tag);
tagsToRegister = test.AsEnumerable<string>();
switch (Reg.Platform)
{
case "mpns":
registration = new MpnsRegistrationDescription(Reg.Handle);
break;
case "wns":
registration = new WindowsRegistrationDescription(Reg.Handle);
break;
case "apns":
registration = new AppleRegistrationDescription(Reg.Handle);
break;
case "gcm":
registration = new GcmRegistrationDescription(Reg.Handle);
break;
default:
throw new HttpResponseException(HttpStatusCode.BadRequest);
}
var regID = await hub.Post(Services);
registration.RegistrationId = regID;
db.NotificationTags.Add(new DataObjects.NotificationTag() { User = user, tag = user.Username, RegistrationID = registration.RegistrationId });
hub.updateRegistration(registration, test);
db.SaveChanges();
}
else
{
RegisterController.DeviceRegistration Reg = CreateDeviceRegistration(user.PushChannelUri, sendTAGs);
Microsoft.Azure.NotificationHubs.RegistrationDescription registration = null;
//Microsoft.ServiceBus.Notifications.RegistrationDescription registration = null;
switch (Reg.Platform)
{
case "mpns":
registration = new MpnsRegistrationDescription(Reg.Handle);
break;
case "wns":
registration = new WindowsRegistrationDescription(Reg.Handle);
break;
case "apns":
registration = new AppleRegistrationDescription(Reg.Handle);
break;
case "gcm":
registration = new GcmRegistrationDescription(Reg.Handle);
break;
default:
throw new HttpResponseException(HttpStatusCode.BadRequest);
}
registration.RegistrationId = userTags[0].RegistrationID;
IEnumerable<string> tagsToRegister;
List<string> test = new List<string>();
foreach (DataObjects.NotificationTag t in userTags)
test.Add(t.tag);
test.Add(Tag);
tagsToRegister = test.AsEnumerable<string>();
hub.updateRegistration(registration, test);
}
}
return true;
}
private RegisterController.DeviceRegistration CreateDeviceRegistration(string channelUri, List<string> tags)
{
return new RegisterController.DeviceRegistration() { Platform = "wns", Handle = channelUri, Tags = tags.ToArray<string>() };
}
New image
I really do not understand it, sometimes I have three registrations, but then in the counter in the bottom is still only saying 2 ? How can this be?
(The view is from the server explorer in VS2013)

Test AsycAction in C#

I have this code below, about a class responsible for handle exceptions and log them.
using ProReserve.Reserve.Domain.Licenciados;
using ProReserve.Reserve.Domain.Sistema.Logging;
using ProReserve.Reserve.Domain.Usuarios;
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http.Controllers;
namespace ProReserve.Reserve.API.Filters
{
public class DefaultControllerActionInvoker : ApiControllerActionInvoker
{
private Func<HttpRequestMessage, ILoggingService> _getLoggingService;
public DefaultControllerActionInvoker(Func<HttpRequestMessage, ILoggingService> getLoggingService)
{
_getLoggingService = getLoggingService;
}
public override async Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
{
Task<HttpResponseMessage> actionTask = base.InvokeActionAsync(actionContext, cancellationToken); // (*)
if (actionTask.Exception != null &&
actionTask.Exception.GetBaseException() != null &&
actionContext.Request.Properties["Licenciado"] as Licenciado != null)
{
var exception = actionTask.Exception.GetBaseException();
Operacao operacao = this.getHttpStatusCode(actionTask.Result);
await SaveLogAsync(exception, actionContext.Request, operacao);
return await Task.Run(() => new HttpResponseMessage(actionTask.Result.StatusCode)
{
Content = new StringContent(exception.Message),
ReasonPhrase = "Error"
});
}
return await actionTask;
}
private async Task SaveLogAsync(Exception exception, HttpRequestMessage request, Operacao operacao)
{
var guidLog = string.Format("{0}{1}", DateTime.Now.Ticks, Thread.CurrentThread.ManagedThreadId);
var requestInfo = string.Format("{0} {1}", request.Method, request.RequestUri);
var httpContext = request.Properties["MS_HttpContext"] as HttpContextBase;
var remoteAddr = httpContext.Request.ServerVariables["REMOTE_ADDR"];
var serverName = httpContext.Request.ServerVariables["SERVER_NAME"];
var logonUser = httpContext.Request.ServerVariables["LOGON_USER"];
var usuario = request.Properties["Usuario"] as Usuario;
var message = string.Format("{0} {1}", exception.Message.ToString(), exception.InnerException != null ? exception.InnerException.ToString() : string.Empty);
var logEntry = new Log(guidLog, operacao)
{
IDUsuario = usuario.ID,
IPCliente = remoteAddr,
IPServidor = serverName,
MaquinaCliente = logonUser,
Mensagem = string.Format(#"RequestInfo: {0} - Error: {1}", requestInfo, message),
};
using (var loggingService = _getLoggingService.Invoke(request))
{
loggingService.Licenciado = (Licenciado)request.Properties["Licenciado"];
await Task.Run(() => loggingService.Inserir(logEntry));
}
}
private Operacao getHttpStatusCode(HttpResponseMessage response)
{
Operacao operacao = Operacao.Response;
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
switch (response.StatusCode)
{
case System.Net.HttpStatusCode.BadRequest: //400
operacao = Operacao.BadGateway;
break;
case System.Net.HttpStatusCode.Unauthorized: //401
operacao = Operacao.Unauthorized;
break;
case System.Net.HttpStatusCode.PaymentRequired: //402
operacao = Operacao.PaymentRequired;
break;
case System.Net.HttpStatusCode.Forbidden: //403
operacao = Operacao.Forbidden;
break;
case System.Net.HttpStatusCode.NotFound: //404
operacao = Operacao.NotFound;
break;
case System.Net.HttpStatusCode.MethodNotAllowed: //405
operacao = Operacao.MethodNotAllowed;
break;
case System.Net.HttpStatusCode.NotAcceptable: //406
operacao = Operacao.NotAcceptable;
break;
case System.Net.HttpStatusCode.ProxyAuthenticationRequired: //407
operacao = Operacao.ProxyAuthenticationRequired;
break;
case System.Net.HttpStatusCode.RequestTimeout: //408
operacao = Operacao.RequestTimeout;
break;
case System.Net.HttpStatusCode.Conflict: //409
operacao = Operacao.Conflict;
break;
case System.Net.HttpStatusCode.Gone: //410
operacao = Operacao.Gone;
break;
case System.Net.HttpStatusCode.LengthRequired: //411
operacao = Operacao.LengthRequired;
break;
case System.Net.HttpStatusCode.PreconditionFailed: //412
operacao = Operacao.PreconditionFailed;
break;
case System.Net.HttpStatusCode.RequestEntityTooLarge: //413
operacao = Operacao.RequestEntityTooLarge;
break;
case System.Net.HttpStatusCode.RequestUriTooLong: //414
operacao = Operacao.RequestUriTooLong;
break;
case System.Net.HttpStatusCode.UnsupportedMediaType: //415
operacao = Operacao.UnsupportedMediaType;
break;
case System.Net.HttpStatusCode.RequestedRangeNotSatisfiable: //416
operacao = Operacao.RequestedRangeNotSatisfiable;
break;
case System.Net.HttpStatusCode.ExpectationFailed: //417
operacao = Operacao.ExpectationFailed;
break;
case System.Net.HttpStatusCode.InternalServerError: //500
operacao = Operacao.InternalServerError;
break;
case System.Net.HttpStatusCode.NotImplemented: //501
operacao = Operacao.NotImplemented;
break;
case System.Net.HttpStatusCode.BadGateway: //502
operacao = Operacao.BadGateway;
break;
case System.Net.HttpStatusCode.ServiceUnavailable: //503
operacao = Operacao.ServiceUnavailable;
break;
case System.Net.HttpStatusCode.GatewayTimeout: //504
operacao = Operacao.GatewayTimeout;
break;
case System.Net.HttpStatusCode.HttpVersionNotSupported: //505
operacao = Operacao.HttpVersionNotSupported;
break;
default:
operacao = Operacao.Response; //51
break;
}
}
return operacao;
}
}
}
In the line (*) - Task<HttpResponseMessage> actionTask = base.InvokeActionAsync(actionContext, cancellationToken);) - I have a command that intercepts an action async invoke. The variable actionTask returns with some properties. I need two of those properties filled, not null. They are:
Result -> get the StatusCode returned
Exception -> get the exception returned
I need both of those properties loaded, but I can't do a unit test where both of them are not null. In some test, Result comes not null, and other test, Exception comes not null, but never both of them.
Below is my unit test:
[TestMethod]
public void ActionAsync_Com_Exception()
{
// Arrange
Log log = null;
_loggingService.SetupSet(l => l.Licenciado = _licenciado);
_loggingService.Setup(a => a.Inserir(It.IsAny<Log>()))
.Callback<Log>((l) =>
{
log = l;
});
//Task<object> task1 = Task<object>.Factory.StartNew(() => new Exception()); //(3)
Task<object> task1 = Task<object>.Factory.StartNew(() =>
{
object myClass = new object();
return myClass;
});
//_actionDescriptor.Setup(a => a.ExecuteAsync(It.IsAny<HttpControllerContext>(), It.IsAny<IDictionary<string, object>>(), It.IsAny<CancellationToken>()))
// .Throws(new Exception("exception")); //(1)
_actionDescriptor.Setup(a => a.ExecuteAsync(It.IsAny<HttpControllerContext>(), It.IsAny<IDictionary<string, object>>(), It.IsAny<CancellationToken>()))
.Returns(task1); //(2)
DefaultControllerActionInvoker actionInvoker = new DefaultControllerActionInvoker(r => _loggingService.Object);
// Act
HttpResponseMessage response = actionInvoker.InvokeActionAsync(_baseActionContext, CancellationToken.None).Result;
// Assert
Assert.AreEqual(HttpStatusCode.InternalServerError, response.StatusCode);
Assert.AreEqual("Error", response.ReasonPhrase);
Assert.AreEqual("127.0.0.1", log.IPCliente);
Assert.AreEqual("0.0.0.0", log.IPServidor);
Assert.AreEqual("USER\\MACHINE", log.MaquinaCliente);
Assert.AreEqual("RequestInfo: POST http://localhost/teste - Error: exception ", log.Mensagem);
_loggingService.VerifySet(l => l.Licenciado = _licenciado);
_loggingService.Verify(a => a.Inserir(It.IsAny<Log>()));
_loggingService.Verify(a => a.Dispose());
}
In my test I have tried:
(1) In this case, it returns an exception, but Result property comes null.
(2) In this case, it returns a result, but Exception property comes null. In this case, I need also to mock some way, to return some error statuscode (40x or 50x). But I donĀ“t know what to do.
(3) I have already tried creating a task which fires an exception, but gets into the case (2) above
So, I can't make my unit test works as well.
What do I need to do in my unit test code to get those two properties loaded?
Not sure I'm following what's going on in your code, but the bottom line is that you have asynchronous completion going on, for which your test assertions are not waiting. It means that the assertions are executing while or perhaps before the asynchronous code executes, so they don't test the results.
The standard test framework doesn't adequately support async/await, so if you're calling a method returning something of Task, you have to wait on the task - essentially make your test code synchronous... given what you've done, I think one extra line may do the trick:
// Act
HttpResponseMessage response = actionInvoker.InvokeActionAsync(_baseActionContext, CancellationToken.None).Result;
// After you have obtained the returned Task object,
// and done whatever will initiate the asynchronous activity, wait for it to complete...
task1.Wait(); // <-- Try this
// Assert
Assert.AreEqual(HttpStatusCode.InternalServerError, response.StatusCode);

How to deserialize a UDPTunnel in protobuf.net

I'm doing a voip client code with mumble in Unity3d (c# scripting) and now I'm able to successfully connect to any of mumble public server. But when I try to deserialize a UDP tunnel I get a lot of exceptions including 'invalid wiretype', 'number overflow', 'invalid field', 'endofstream', 'wrong group was ended' and bla bla... all of the at this particular line.
var udpTunnel = Serializer.DeserializeWithLengthPrefix<UDPTunnel> (_ssl, PrefixStyle.Fixed32BigEndian);
where _ssl is SslStream
Here is my complete method
nternal void ProcessTcpData ()
{
try {
var masg = IPAddress.NetworkToHostOrder (_reader.ReadInt16 ());
MessageType messageType = (MessageType)masg;
Debug.Log ("Received message type: " + messageType);
switch (messageType) {
case MessageType.Version:
_mc.RemoteVersion = Serializer.DeserializeWithLengthPrefix<Version> (_ssl,
PrefixStyle.Fixed32BigEndian);
break;
case MessageType.CryptSetup:
var cryptSetup = Serializer.DeserializeWithLengthPrefix<CryptSetup> (_ssl,
PrefixStyle.Fixed32BigEndian);
ProcessCryptSetup (cryptSetup);
break;
case MessageType.CodecVersion:
_mc.CodecVersion = Serializer.DeserializeWithLengthPrefix<CodecVersion> (_ssl,
PrefixStyle.Fixed32BigEndian);
break;
case MessageType.ChannelState:
_mc.ChannelState = Serializer.DeserializeWithLengthPrefix<ChannelState> (_ssl,
PrefixStyle.Fixed32BigEndian);
break;
case MessageType.PermissionQuery:
_mc.PermissionQuery = Serializer.DeserializeWithLengthPrefix<PermissionQuery> (_ssl,
PrefixStyle.Fixed32BigEndian);
break;
case MessageType.UserState:
_mc.UserState = Serializer.DeserializeWithLengthPrefix<UserState> (_ssl,
PrefixStyle.Fixed32BigEndian);
break;
case MessageType.ServerSync:
_mc.ServerSync = Serializer.DeserializeWithLengthPrefix<ServerSync> (_ssl,
PrefixStyle.Fixed32BigEndian);
_mc.ConnectionSetupFinished = true;
break;
case MessageType.ServerConfig:
_mc.ServerConfig = Serializer.DeserializeWithLengthPrefix<ServerConfig> (_ssl,
PrefixStyle.Fixed32BigEndian);
_validConnection = true; // handshake complete
break;
case MessageType.TextMessage:
var textMessage = Serializer.DeserializeWithLengthPrefix<TextMessage> (_ssl, PrefixStyle.Fixed32BigEndian);
break;
case MessageType.UDPTunnel:
if (_validConnection) {
var udpTunnel = Serializer.DeserializeWithLengthPrefix<UDPTunnel> (_ssl, PrefixStyle.Fixed32BigEndian);
}
break;
case MessageType.Ping:
var ping = Serializer.DeserializeWithLengthPrefix<MumbleProto.Ping> (_ssl, PrefixStyle.Fixed32BigEndian);
Debug.Log ("Received ping: " + ping.timestamp + ", udp: " + ping.udp_packets + ", tcp:" +
ping.tcp_packets);
break;
case MessageType.Reject:
var reject = Serializer.DeserializeWithLengthPrefix<Reject> (_ssl,
PrefixStyle.Fixed32BigEndian);
_validConnection = false;
_errorCallback ("Mumble server reject: " + reject.reason, true);
break;
default:
_errorCallback ("Message type " + messageType + " not implemented", true);
break;
}
if (_validConnection) {
Debug.Log ("Handshake Complete:\tconnection is valid");
}
} catch (Exception ex) {
Debug.LogException (ex);
}
}
_reader is a BinaryReader
I've got past this by using
var size = IPAddress.NetworkToHostOrder (_reader.ReadInt32 ());
var udpTunnel = new UDPTunnel { packet = _reader.ReadBytes(size) };
Now I don't know why Deserializewithlengthprefix was not working because as I understand, these lines are doing the same thing.

C2DM-Sharp Error:Invalid registration

i am using c2dm-sharp for sending push notification to android device.
i was working fine but from some time its showing some error: message failed invalid registration
when i debug the code i found that in C2dmMessageTransport.cs file of C2dmSharp.Server project in below method its giving error at var webResp = webReq.GetResponse() as HttpWebResponse;
error is - the underlying connection was closed an unexpected error occurred on a send
static C2dmMessageTransportResponse send(C2dmMessage msg, string googleLoginAuthorizationToken, string senderID, string applicationID)
{
C2dmMessageTransportResponse result = new C2dmMessageTransportResponse();
result.Message = msg;
var postData = msg.GetPostData();
var webReq = (HttpWebRequest)WebRequest.Create(C2DM_SEND_URL);
// webReq.ContentLength = postData.Length;
webReq.Method = "POST";
webReq.ContentType = "application/x-www-form-urlencoded";
webReq.UserAgent = "C2DM-Sharp (version: 1.0)";
webReq.Headers.Add("Authorization: GoogleLogin auth=" + googleLoginAuthorizationToken);
using (var webReqStream = new StreamWriter(webReq.GetRequestStream(), Encoding.ASCII))
{
var data = msg.GetPostData();
webReqStream.Write(data);
webReqStream.Close();
}
try
{
var webResp = webReq.GetResponse() as HttpWebResponse;
if (webResp != null)
{
result.ResponseStatus = MessageTransportResponseStatus.Ok;
//Check for an updated auth token and store it here if necessary
var updateClientAuth = webResp.GetResponseHeader("Update-Client-Auth");
if (!string.IsNullOrEmpty(updateClientAuth) && C2dmMessageTransport.UpdateGoogleClientAuthToken != null)
UpdateGoogleClientAuthToken(updateClientAuth);
//Get the response body
var responseBody = "Error=";
try { responseBody = (new StreamReader(webResp.GetResponseStream())).ReadToEnd(); }
catch { }
//Handle the type of error
if (responseBody.StartsWith("Error="))
{
var wrErr = responseBody.Substring(responseBody.IndexOf("Error=") + 6);
switch (wrErr.ToLower().Trim())
{
case "quotaexceeded":
result.ResponseStatus = MessageTransportResponseStatus.QuotaExceeded;
break;
case "devicequotaexceeded":
result.ResponseStatus = MessageTransportResponseStatus.DeviceQuotaExceeded;
break;
case "invalidregistration":
result.ResponseStatus = MessageTransportResponseStatus.InvalidRegistration;
break;
case "notregistered":
result.ResponseStatus = MessageTransportResponseStatus.NotRegistered;
break;
case "messagetoobig":
result.ResponseStatus = MessageTransportResponseStatus.MessageTooBig;
break;
case "missingcollapsekey":
result.ResponseStatus = MessageTransportResponseStatus.MissingCollapseKey;
break;
default:
result.ResponseStatus = MessageTransportResponseStatus.Error;
break;
}
throw new MessageTransportException(wrErr, result);
}
else
{
//Get the message ID
if (responseBody.StartsWith("id="))
result.MessageId = responseBody.Substring(3).Trim();
}
}
}
catch (WebException webEx)
{
var webResp = webEx.Response as HttpWebResponse;
if (webResp != null)
{
if (webResp.StatusCode == HttpStatusCode.Unauthorized)
{
//401 bad auth token
result.ResponseCode = MessageTransportResponseCode.InvalidAuthToken;
result.ResponseStatus = MessageTransportResponseStatus.Error;
throw new InvalidAuthenticationTokenTransportException(result);
}
else if (webResp.StatusCode == HttpStatusCode.ServiceUnavailable)
{
//First try grabbing the retry-after header and parsing it.
TimeSpan retryAfter = new TimeSpan(0, 0, 120);
var wrRetryAfter = webResp.GetResponseHeader("Retry-After");
if (!string.IsNullOrEmpty(wrRetryAfter))
{
DateTime wrRetryAfterDate = DateTime.UtcNow;
if (DateTime.TryParse(wrRetryAfter, out wrRetryAfterDate))
retryAfter = wrRetryAfterDate - DateTime.UtcNow;
else
{
int wrRetryAfterSeconds = 120;
if (int.TryParse(wrRetryAfter, out wrRetryAfterSeconds))
retryAfter = new TimeSpan(0, 0, wrRetryAfterSeconds);
}
}
//503 exponential backoff, get retry-after header
result.ResponseCode = MessageTransportResponseCode.ServiceUnavailable;
result.ResponseStatus = MessageTransportResponseStatus.Error;
throw new ServiceUnavailableTransportException(retryAfter, result);
}
}
}
return result;
}
i am stuck here please help me.
is any thing i am missing
Have you signed up for the C2DM service and put your personal key in? http://code.google.com/android/c2dm/signup.html
The code you are receiving is documented here:
http://code.google.com/android/c2dm/index.html#push
P.S. I obtained both of these links from here: https://github.com/Redth/C2DM-Sharp Under the How do I use it? and Links sections.

Categories