when i disconnect my server , the application throws an error saying
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to
objects owned by a different thread. Current thread be0cf8. Receiver
'' (of type 'QNativeSocketEngine') was created in thread cc39d4"
I am not under standing what is causing the problem
i have three threads running in my application ,
MainWindow.cpp:
void MainWindow::on_pushbutton_clicked()
{
ui->pushbutton->setDisabled(true);
thread1.m_TargetIpAddress.setAddress(IP Address);
thread1.m_iTargetPort = ui->TargetPortNumber->text().toInt();
thread1.start();
thread2.start();
}
1st thread :
some of the socket operations like send , receive , connecttotarget , disconnectfrom host are done here
2nd thread :
i will connect to server from second thread.
3rd thread :
In this i will continuously send some command and receive some data from server.
I am using while(var) , when ever connection is established this var value will be updated to one and when ever server disconnects var value is updated as 0(zero) . thread 3 will be started once connection is established with server .
These are my sequence . Now my problem is when the server disconnects , I dont get the disconnected signal emitted from my application .
this is my signal and slot
connect(&obj, &QTcpSocket::disconnected,this,&MainWindow::TargetConnectionStatus,Qt::UniqueConnection);
TargetConnectionStatus()
{
var = 0;
}
as this slots is not being emitted the thread is continuously running and suddenly this assert failure occurs , How to solve this error .
Related
I am new to GRPC so please let me know if I am doing something wrong here. I am looking at the greeter_async_server.cc example code. This seems to work fine for normal requests but I wanted to simulate a request getting stuck on the server so I added a sleep in the processing loop. I added this right before Finish is called on the responder so that it was in the actual processing logic of the request. While the server thread is sleeping it will not accept any new requests until the thread is free. I attempted to create another client request while the original request on the server is sleeping but the grpc server would not process the request. The client seemed to be stuck until the server came out of the sleep.
I also broke this process into debugger as well but the only request I saw was the one that was sleeping. The other threads were waiting on the completion queue.
I am new to grpc so if I am doing this wrong please let me know what I need to do to handle request while another request is stuck.
void Proceed() {
if (status_ == CREATE) {
// Make this instance progress to the PROCESS state.
status_ = PROCESS;
// As part of the initial CREATE state, we *request* that the system
// start processing SayHello requests. In this request, "this" acts are
// the tag uniquely identifying the request (so that different CallData
// instances can serve different requests concurrently), in this case
// the memory address of this CallData instance.
service_->RequestSayHello(&ctx_, &request_, &responder_, cq_, cq_,
this);
} else if (status_ == PROCESS) {
// Spawn a new CallData instance to serve new clients while we process
// the one for this CallData. The instance will deallocate itself as
// part of its FINISH state.
new CallData(service_, cq_);
// The actual processing.
std::string prefix("Hello ");
reply_.set_message(prefix + request_.name());
Sleep((DWORD)-1);
// And we are done! Let the gRPC runtime know we've finished, using the
// memory address of this instance as the uniquely identifying tag for
// the event.
status_ = FINISH;
responder_.Finish(reply_, Status::OK, this);
} else {
GPR_ASSERT(status_ == FINISH);
// Once in the FINISH state, deallocate ourselves (CallData).
delete this;
}
}
I am new to win32 api progamming, and I am tring writing a xmpp client for windows platform, using win32 api and gloox xmpp library. gloox has its own event loop, while windows GUI has message loop too. I am not very clear how to use these two loops together.
From the gloox document:
Blocking vs. Non-blocking Connections
For some kind of bots a blocking connection (the default behaviour) is ideal. All the bot does is react to events coming from the server. However, for end user clients or anything with a GUI this is far from perfect.
In these cases non-blocking connections can be used. If ClientBase::connect( false ) is called, the function returnes immediately after the connection has been established. It is then the resposibility of the programmer to initiate receiving of data from the socket.
The easiest way is to call ClientBase::recv() periodically with the desired timeout (in microseconds) as parameter. The default value of -1 means the call blocks until any data was received, which is then parsed automatically.
Window message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
Window proc:
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
TCHAR str[100];
StringCbPrintf(str, _countof(str), TEXT("Message ID:%-6x:%s"), msg, GetStringMessage(msg));
OutputDebugString(str);
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch (msg)
{
case WM_CREATE:
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rect);
DrawText(hdc, TEXT("DRAW TEXT ON CLIENT AREA"), -1, &rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
gloox blocking connection
JID jid( "jid#server/resource" );
Client* client = new Client( jid, "password" );
client->registerConnectionListener( this );
client->registerPresenceHandler( this );
client->connect();// here will enter event loop
gloox non-blocking connection
Client* client = new Client( ... );
ConnectionTCPClient* conn = new ConnectionTCPClient( client, client->logInstance(), server, port );
client->setConnectionImpl( conn );
client->connect( false );
int sock = conn->socket();
[...]
I am not very clear how can I
call ClientBase::recv() periodically with the desired timeout (in microseconds) as parameter
With a timer ? or multi thread programming ? or there is a better solution ?
Any suggestions appreciated
Thank you
The best IO strategy for that is overlapped IO. Unfortunately, the method is windows only, not supported by the cross-platform library you’ve picked.
You can use SetTimer() API, and periodically call recv() method of the library with zero timeout, in WM_TIMER handler. This will introduce extra latency (your PC receives a message but it has to wait for the next timer event to handle it), or if you’ll use small intervals like 20 ms, will consume battery on laptops or tablets.
You can use blocking API with a separate thread. More efficient performance-wise, but harder to implement, you’ll have to marshal messages and other events to the GUI thread. WM_USER+n custom windows messages is usually the best way to do that, BTW.
When the socket times out while waiting for a read it occasionally fails. But when it does fail, it continuously fails, and the log message in slotDisconnected never gets reported despite mpSocket's disconnected signal being connected to slotDisconnect(). It's as if the return statement in slotConnected isn't being hit and it's going round in a continous loop.
void Worker::slotDisconnected()
{
// Attempt to reconnect
log("Disconnected from Server. Attempting to reconnect...");
// fires mpSocket's connect signal (which is connected to slotConnected)
connectToServer();
}
void Worker::slotConnected()
{
// Loop forever while connected and receiving messages correctly
while(1)
{
if(mpSocket->bytesAvailable())
{
// A message is ready to read
}
else if(!mpSocket->waitForReadyRead(mSocketTimeOut))
{
// waitForReadyRead returned false - instead of continuing and trying again, we must disconnect as sometimes
// (for some unknown reason) it gets stuck in an infinite loop without disconnecting itself as it should
log("Socket timed out while waiting for next message.\nError String: " + mpSocket->errorString());
msleep(3000);
mpSocket->disconnect();
return;
}
}
}
The signals/slots are connected like so:
connect(mpSocket, &QAbstractSocket::disconnected, this, &TRNGrabberWorker::slotDisconnected);
connect(mpSocket, &QAbstractSocket::connected, this, &TRNGrabberWorker::slotConnected);
Anyone have any idea's what's going on? Would be much appreciated
To disconnect from server use mpSocket->disconnectFromHost(); instead of mpSocket->disconnect();.
Actually mpSocket->disconnect(); disconnects all signals/slots of object mpSocket.
I use SignalR 2.0.0 Win2012 iis8 with two environment with two different ips.
one environment service is up and second is down(purposely)
use websocket protocol.
i have the following scenario:
When i connect to first environment and want to connect to the second.
i disconnected from first environment and try connect to second environment i get error(its correct behavior)
i try to reconnect back to the first environment but I get still the same error.
the error is "Error during negotiation request."
after refresh the browser i can connect success again to first environment.
What am i doing wrong?
this is part of my code:
function connect(host)
{
var hubConnection = $.hubConnection.('');
hubConnection.url = host;
hubConnection.start()
.done(open)
.fail(error);
}
function open()
{
console.log('login success')
}
function disconnect()
{
var self = this,
hubConnection = $.hubConnection("");
console.log('disconnect ')
hubConnection.stop(true, true);
}
function error(error)
{
var self = this,
hubConnection = $.hubConnection("");
console.log('connection error ')
if(error && hubConnection.state !== $.connection.connectionState.connected)
{
.....
.....
//logic detemninate wich environment ip was previous
connect(environment ip)
}
}
//occured when button disconnect clicked
function disconnectFromFirstEnvironmentAndConnectToSecond()
{
disconect();
connect(second environment ip);
}
.....
.....
connect(first environment ip);
You're not retaining your first connection reference.
Aka you create a HubConnection and then never capture it in a scope that can be used later; therefore when you disconnect later the connection.stop does nothing because it's not calling stop on the HubConnection that was originally started.
This could ultimately lead to you having too many concurrently open requests which will then not allow you to negotiate with a server hence your error.
I'd recommend fixing how you stop/start connections. Next if the issue still occurs I'd inspect the network traffic to ensure that valid requests are being made.
I am using the new Akka IO and followed this tutorial(which is a simple server-client application). My server actor system code looks like this:
// create the sever system
ActorSystem tcpServerSystem = ActorSystem.create("tcp-server-system");
// create the tcp actor
final ActorRef tcpServer = Tcp.get(tcpServerSystem).manager();
// create the server actor;
ActorRef serverActor = tcpServerSystem.actorOf(new Props(ServerActor.class).withRouter(new RoundRobinRouter(5)), "server");
// tell the tcp server to use an actor for listen connection on;
final List<Inet.SocketOption> options = new ArrayList<Inet.SocketOption>();
options.add(TcpSO.reuseAddress(true));
tcpServer.tell(TcpMessage.bind(serverActor, new InetSocketAddress("127.0.0.1", 12345), 10, options),
serverActor);
The ServerActor class it's just a plain actor that on it's onReceive does the followings:
logger.info("Received: " + o);
if (o instanceof Tcp.Connected){
connectionActor = getSender();
connectionActor.tell(TcpMessage.register(getSelf()), getSelf());
ByteStringBuilder byteStringBuilder = new ByteStringBuilder();
byteStringBuilder.putBytes("Hello Worlds".getBytes());
connectionActor.tell(TcpMessage.write(byteStringBuilder.result()), getSelf());
}
I am trying to test the server actor using netcat and have this "strange" behaviour: only the first client that connect tot the server is receiving the message send from the server. The nexts clients could connect to the server but does not receive the message. Also in debug mode the server actor doesn't get the Tcp.Connected message(except for the first connected client), so a registration message could not be sent to the client, althought the next clients could connect.
this is a known issue in the 2.2-M1 milestone, where the problem was that the TcpListener didn't register AcceptInterest on the selector unless it reached the configured BatchAcceptLimit, leading to it not being notified of new accepts if there where only a few connections pending.
It has been fixed and will be part of the next milestone release.