How to disconnect an rtmp connection? - red5

Do you know if it's possible actually to disconnect a rtmpconnection and how ?
There is no "disconnect" method in the official doc, and also in the rtmpconnection.lzx . So if you know a way out to disconnect the rtmp connection,please let me know. Thanks in advance.

The <rtmpconnection> class in OpenLaszlo uses the ActionScript 3 NetConnection class to connect to the server. The NetConnection class has a method close(), here is the documentation for that:
Closes the connection that was opened locally or to the server and
dispatches a netStatus event with a code property of
NetConnection.Connect.Closed.
This method disconnects all NetStream objects running over the
connection. Any queued data that has not been sent is discarded. (To
terminate local or server streams without closing the connection, use
NetStream.close().) If you close the connection and then want to
create a new one, you must create a new NetConnection object and call
the connect() method again.
The close() method also disconnects all remote shared objects running
over this connection. However, you don't need to recreate the shared
object to reconnect. Instead, you can just call SharedObject.connect()
to reestablish the connection to the shared object. Also, any data in
the shared object that was queued when you issued
NetConnection.close() is sent after you reestablish a connection to
the shared object.
With Flash Media Server, the best development practice is to call
close() when the client no longer needs the connection to the server.
Calling close() is the fastest way to clean up unused connections. You
can configure the server to close idle connections automatically as a
back-up measure.
In the LZX source code for the <rtmpconnection> I can see that NetConnection.close() is only called in case of a connection failure:
<!--- Handle connection failure, attempt to reconnect using altsrc
#keywords private -->
<method name="_handleConnectionFailure" args="msg"><![CDATA[
this._nc.close();
if (this.debug) {
if ($debug) Debug.warn("error connecting to", this._connecturl, ":", msg);
}
....
I don't know why there is no close method defined on the <rtmpconnection> class, but you could add that code for your yourself, by extending the <rtmpconnection> and adding a close method. Just make sure you handle the state variables correctly.
As I haven't used Red5 in a long time, I cannot tell you if Red5 automatically closes NetConnections which are idle.

Related

Connection to database not closing

I'm using "redis-rs" for rust and I tested sending a few thousand requests locally
and it works really well at the few first, except that at some point it stops accepting requests
and starts showing me this error when I send a command to redis:
"Only one usage of each socket address (protocol/network address/port) is normally permitted"
I am opening a client and a connection on every request to the http server that takes them in,
that's probably a bad idea in the first place, but shouldn't the connections stop existing and close after the function that opened it ends?
Is there any better solution, like some kind of global connection?
thanks
Well if it is an http server, the crate you are using likely is doing multithreading to handle requests. It is possible that one thread got caught in the process of closing the connection just as another thread began processing the next request.
Or in your case, maybe the remote database has not finished closing the previous request by the time the next connection is created. Either way, it's easier to think of it as a race condition between threads.
Since you don't know what thread will request a connection next, it may be better to store the connection as a global resource. Since I assume a mutex lock is faster than opening and closing a socket, I used lazy_static to create a single thread safe connection.
use lazy_static::lazy_static;
use parking_lot::Mutex;
use std::sync::Arc;
lazy_static! {
pub static ref LOCAL_DB: Arc<Mutex<Connection>> = {
let connection = Connection::open("local.sqlite").expect("Unable to open local DB");
connection.execute_batch(CREATE_TABLE).unwrap();
Arc::new(Mutex::new(connection))
};
}
// I can then just use it anywhere in functions without any complications.
let lock = LOCAL_DB.lock();
lock.execute_batch("begin").unwrap();
// etc.

Indy Server and AdoQuery are conflicting

I have two programs one is a client the other is a server for the client.
The client sends some data to the server like this and then reads the response:
idtcpclient1.WriteLn(command); //Command contains data that the server needs eg. name and surname
progressbar1.StepIt;
sresult := idtcpclient1.ReadLn();
The server then reads the line, manipulates it and creates a SQL Query.
adoquery1.Close;
adoquery1.SQL.Text := 'select * from '+sGrade;
adoquery1.Open;
But as soon as it opens the connection to the database the client gives an error "Connection closed gracefully"
I have tested the server code without the client by simulating the input and it works fine.
I think Indy and AdoQuery are conflicting
If so why and how can I fix it
If not then what is the problem and how should I fix it?
ADO uses apartment-threaded COM objects that have an affinity to the thread that creates them. They cannot be used across thread boundaries unless they are marshalled.
Indy's TCP server is multi-threaded. Each client runs in its own thread.
A thread must call CoInitialize/Ex() to establish its relationship with COM before it can then access any COM objects, and call CoUninitialize() when it is done using COM.
Your server fails because it is raising an uncaught exception that disconnects the client. Most likely because you did not initialize COM.
You need to create ADO objects on a per-client basis, do not use them from the main thread. In the server's OnConnect event, call CoInitialize/Ex(). In the OnDisconnect event, call CoUninitialize(). In the OnExecute event, dynamically create and use new ADO objects as needed.
This does mean that each client will need its own database connection. If you do not want that, then move your ADO logic to a dedicated thread that clients can post requests to when needed. Stay away from doing the database work in the main thread, it does not belong there.
If you use datamodules: you can create one instance of the datamodule per client, to avoid threading errors. Indy can hold a reference to the client's datamodule in the context. Or use a pool of datamodule instances, depending on available resources and traffic.

Close The Socket?

I have an application that needs to stream data up to a server over a particular port. When the application starts it performs a number of checks, for network connectivity, a reachable host, among others. I'd like it to also check the port to ensure it's able to receive data.
I have this code:
Private Function CheckPort(ByVal Host As String) As Boolean
Dim IPs() As IPAddress = Dns.GetHostAddresses(Host)
Dim s As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
s.Connect(IPs(0), <port # removed>)
If s.Poll(-1, SelectMode.SelectWrite) Then
Return True
End If
Return False
End Function
The code works well, but I'm concerned that by performing the check I might be inadvertently preventing subsequent messages from the application from reaching the port. Will performing this check interfere with the actual data I want to send to the host? Should I close the socket with s.close() before returning the function?
I mainly agree with CodeCaster's response.
If you say the server is buggy, it is also probable that a few minutes after you check the port connection, the connection is broken or even closed by the server.
If you still want to do it as a means to reduce risk of making the user write some message that later cannot be sent, this would be a good approach to follow. An alternative is that you can save the data as draft locally or somewhere else for sending it later when the server is available.
Now, going to your code:
You are opening a connection inside function CheckPort so when the function finishes you will lose any reference to s, the open socket. In C, you would have a leak of resources; in Java, a garbage collector will take care of the Socket and close it. I don't know how it is in VB but I'd close that socket before leaving the function. In any case it's a healthy practice.
Additionally, when you have data ready to send you won't be able to do it on the same connection if you lose the reference (s) to the open socket or you close the socket (unless VB has any trick that I don't know). You will have to open a new connection to send data. Don't worry, you will be able to do it even if you made the check before. The server will see it as just a different connection, maybe from a different source port (or could be the same if you closed the connection before, that depends on the OS).
Checking a port before connecting to it is as useful as verifying file existence before opening it: not at all.
The file can be deleted in between checking and opening, and your socket can be closed for a variety of reasons.
Just connect and write to it, it'll throw an appropriate exception when it won't work.

Recover Callback channel after CommunicationObjectAbortedException thrown

We have (Multiple)Clients-(One)Server architecture for poker desktop game. We are using callback Notifications using callback Channels.
But sometimes because of internet connection drops, that particualr client gets disconected from server and that particular's client's WCF channel is also gone to faluted state and his callback Channel which lies in server is also faluted.
Scenario :
That client is playing game, while internet connection drops, that game is stopped, still his game window remains open and when his/her internet connection gets back that client is dropped out from Server, but that player's game window still opens and that player can't do anything as his/her WCF channel is dropped out.
We want to close that particular client's window while he/she is dropped out from server and throwing 'CommunicationObjectAbortedException ' exception.
We can't use previous WCF channel's callback channel as it's in faluted state.
So we have tried to create new callbackChannel in server while dropping using below code :
OperationContext.Current.GetCallbackChannel();
but here Current is showing "NULL" as that player's WCF channel is aborted, so it's throwing an error that "Object reference not set to an instance of object".
So is there any solution to use aborted WCF channel's callback Channel or recover that WCF channel without reinitializing them or to call that client using new channel?
I'd try following:
On server side, when trying to communicate using faulted / aborted chanel - you'll failed.
Catch this failure, and remove its callback from the list (I suppose you manage some callback list).
On client side - when chanel Faulted / ... handled - try to re-open new chanel to server. When this new chenel will be open, on server side place this new callback back to the "valid callbacks" list.

Manage frequently called WCF connection

Maybe I'm missing something basic here, so please correct me if I am. I have a local service and a WinForms app that communicate via WCF, but I seem to end up with a lot of copies of this code in my application:
Public Shared Sub MyLocalMethod1()
Dim tcpBinding As New NetTcpBinding
tcpBinding.SendTimeout = New TimeSpan(0, 0, 5)
Dim tcpFactory As ChannelFactory(Of MyWCFClass.MyWCFInterface) = New _
ChannelFactory(Of MyWCFClass.MyWCFInterface)(tcpBinding, "net.tcp://localhost:4079")
Dim ServiceWCFConnection As MyWCFClass.MyWCFInterface = tcpFactory.CreateChannel
ServiceWCFConnection.MyWCFMethod1()
tcpFactory.Close()
End Sub
I should probably be doing this in some kind of a helper class that creates the connection, lets my service use it, and then closes the connection, so I don't have multiple copies of this connection code. However, should I be leaving this connection open, or does it make sense to close it every time? The WinForm generally calls the service every few seconds, so it may make more sense to try and have a common copy that all these different calls can each access, instead of opening a closing a new connection each time.
It depends on your needs because both approaches are correct. You can wrap your channel creation code into some helper. You will have same functionality as you use at the moment with single place to edit your channel creation code (DRY principle). Usage of the service is slower because each call will create new TCP connection. Use some disposable helper class to represent your created connection.
If you decide to use single channel (proxy) for whole application you have to think about some new complexity. You are using Net.Tcp binding which creates transport session - TCP connection will live for long time. Moreover WCF service instance will live for the same time as the connection because default instancing mode is PerSession. So single service instance will handle all requests from your client = your service will became stateful. Also when you use opened channel for several calls you have to test state of the channel - network problem, server problem, timeout or unhandled exception will switch channel to Faulted state - such channel and related service instance cannot be used any more. You have to abort such channel and open new one.