Clarifying socket handle and server socket handle functional

Posted by Tim Kuehn on 07-Jul-2017 14:01

I'm trying to clarify an ambiguity in the docs - there's reference to a server socket object and a socket object - do these two objects overlap in terms of functionality?

I would expect them to be different in terms of configuration and enabling, and have commonality in terms of sending and receiving data. 

The docs don't make that clear - the server socket docs have this:

  • INSTANTIATING-PROCEDURE attribute,
  • NAME attribute,
  • HANDLE attribute,
  • NEXT-SIBLING attribute,
  • PREV-SIBLING attribute
  • PRIVATE-DATA attribute,
  • SENSITIVE attribute
  • TYPE attribute

Methods

  • DISABLE-CONNECTIONS( ) method
  • ENABLE-CONNECTIONS( ) method,
  • SET-CONNECT-PROCEDURE( ) method 

Events

  • CONNECT event

While the socket docs have 

  • BYTES-READ attribute
  • BYTES-WRITTEN attribute
  • HANDLE attribute
  • INSTANTIATING-PROCEDURE attribute
  • LOCAL-HOST attribute
  • LOCAL-PORT attribute
  • NAME attribute
  • NEXT-SIBLING attribute
  • PREV-SIBLING attribute
  • PRIVATE-DATA attribute
  • REMOTE-HOST attribute
  • REMOTE-PORT attribute
  • SENSITIVE attribute
  • SSL-SERVER-NAME attribute
  • TYPE attribute

Methods

  • CONNECT( ) method (Socket object)
  • CONNECTED( ) method
  • DISCONNECT( ) method (Handle)
  • GET-BYTES-AVAILABLE( ) method
  • GET-SOCKET-OPTION( ) method
  • READ( ) method (Socket)
  • SET-READ-RESPONSE-PROCEDURE( ) method
  • SET-SOCKET-OPTION( ) method
  • WRITE( ) method (Socket)

Some of the socket functionality could apply to server sockets, others clearly do not. Which is which isn't clear. 

All Replies

Posted by jmls on 07-Jul-2017 14:05

server sockets are for a 4GL "socket server" to allow client sockets to connect to

a "socket object" is a client socket that can connect to any tcp server socket (4gl or external)

Posted by jmls on 07-Jul-2017 14:07

*but beware* : sockets can _send_ information in an appserver , but cannot receive data. They _can_ send and receive in a traditional webspeed agent

Posted by jmls on 07-Jul-2017 14:11

have a look at bitbucket.org/.../stompSocketProc.p for a client socket connection to a tcp socket (a stomp mq server socket)

Posted by Laura Stern on 07-Jul-2017 14:12

I don't understand that last comment.  As far as I'm aware, the behavior of ABL sockets are the same in all environments.

Yes, a server-socket allows someone to connect to you.  Once the connection is made a handle to a socket is made available to send/receive data.  Doesn't the doc explain this??  I'll have to check on Monday when I'm in the office.

Posted by jmls on 07-Jul-2017 14:17

Hi Laura - I can promise you that the last time I checked (11.2 ish) this was the case :) . There are no errors, the socket just does not receive the inbound event

I did discuss this and clarify with Mike Jacobs a few years ago and he agreed with me that this was the case, and he understood why it was.

Posted by Tim Kuehn on 07-Jul-2017 14:21

Thx Julian!

Laura - the issue is that there's some functionality that's specific to server sockets (ie ENABLE-CONNECTION()), some that's specific to what I'd call client sockets (ie CONNECT()), and some that's common to both types of socket usage (READ, WRITE, etc.).  

Which is which is which isn't clear in the docs, and that's what I'm trying to sort out. Reason for asking is I'm creating a set of OO classes which wrap all this stuff up in classes, and this ambiguity is preventing me from figuring out what to put where.

Posted by Laura Stern on 07-Jul-2017 14:22

Hmm.  It sounds like a bug to me!  It should either work or it shoud give an error message if you are trying to use something that we know won't work!  

Posted by jmls on 07-Jul-2017 14:25

tim : already done in 2010 ;)

bitbucket.org/.../dotrsocket

Posted by Laura Stern on 07-Jul-2017 14:25

I don't believe that you can read/write on a socket server.  For each method, the doc should show which object(s) it applies to ( n parentheses after the method name).  Again, I will check this on Monday.

Posted by Matt Gilarde on 07-Jul-2017 14:25

Tim - If I'm reading your post correctly, you seem to be wondering why the SERVER-SOCKET handle doesn't support things like READ() and WRITE(). The CONNECT event procedure (which is set with SET-CONNECT-PROCEDURE) receives a socket handle as an input parameter. This is the handle the server uses to read and write on the socket when a connection is made. SERVER-SOCKET doesn't support READ and WRITE directly.

Posted by jmls on 07-Jul-2017 14:27

I'm not sure it's a bug, from what I can remember from what Mike told me it's something to do with the way an appserver client and webspeed client are fired up by the appropriate brokers. The 4gl engine is just fine, but in appserver the socket is not notified by the broker of an inbound socket data packet

Posted by Tim Kuehn on 07-Jul-2017 14:46

[quote user="Matt Gilarde"]Tim - If I'm reading your post correctly, you seem to be wondering why the SERVER-SOCKET handle doesn't support things like READ() and WRITE(). The CONNECT event procedure (which is set with SET-CONNECT-PROCEDURE) receives a socket handle as an input parameter. This is the handle the server uses to read and write on the socket when a connection is made. SERVER-SOCKET doesn't support READ and WRITE directly. [/quote]

So what I'm reading is that the socket server object is just for the server functionality and the AVM creates a new socket object when someone makes a connection.

I'm presuming from this and Julian's code - that also means this socket object created by the AVM has to be cleaned up when it's no longer being used?

I'd note that the sample code in the KB doesn't make this clear: 

knowledgebase.progress.com/.../19882

Posted by jmls on 07-Jul-2017 14:53

one of the advantages of using a class to create a socket is that you can use the destructor to delete the socket handle - as a handle is not garbage collected. I'm sure that you are aware though of the "subscribe" issue where a instance is *not* gc'd if something is subscribing to a class event

Posted by Matt Gilarde on 07-Jul-2017 14:56

[quote user="Tim Kuehn"]

I'm presuming from this and Julian's code - that also means this socket object created by the AVM has to be cleaned up when it's no longer being used?

I'd note that the sample code in the KB doesn't make this clear: 

knowledgebase.progress.com/.../19882

[/quote]
That KB article doesn't show it but this example from the documentation does:
https://documentation.progress.com/output/ua/OpenEdge_latest/index.html#page/dvpin/examples-using-abl-sockets.html

Posted by Tim Kuehn on 07-Jul-2017 15:10

Julian - I remember your stories as if I'd heard them yesterday. :)

Matt - the doc version is indeed quite clearer.

Posted by lecuyer on 07-Jul-2017 17:23

One thing to keep in mind wrt server sockets is that the server socket "listening" behavior (i.e. waiting for CONNECT events) is tied to the avm event processing.  that is, once the socket server is properly set up , the application has to call WAIT-FOR() or PROCESS-EVENTS().  While processing the WAIT-FOR(), if a socket event occurs (i.e. a client connects), it causes the CONNECT event procedure to run.  

This becomes trickier inside an appserver agent, which is only active while running a remote procedure call from a client.  That is, it is not running any ABL code between handling RPC calls.  It is possible to create a socket server inside an agent, but it must happen inside a client RPC call.  Given that, the WAIT-FOR() must necessarily complete in order for the remote procedure call to return to the client.  This means that the appserver agent cannot act as a socket server in the sense that it will accept and process events *between* rpc calls.  This limits its usefulness somewhat in this environment.

The exception to this was the classic webspeed agent.  The normal "idle state" of a classic webspeed agent was Inside a WAIT-FOR statement in the webspeed web-disp.p.  The agent essentially waited on a WAIT-FOR() for web events.  As such, it was possible to set up a server socket that could respond to socket events while the agent was between web calls.

It should be noted that in the PASOE environment, the web interface is supported in the agent using the appserver rpc model (ie. it does NOT use the WAIT-FOR semantics, except as described above).  Therefore, in PASOE, you cannot run the same kind of socket server as in the classic webspeed agent.

Posted by Laura Stern on 07-Jul-2017 17:31

Ah yes!!  Thank you Peter.  Now I remember this.

Posted by Tim Kuehn on 08-Jul-2017 08:15

[quote user="jmls"]

one of the advantages of using a class to create a socket is that you can use the destructor to delete the socket handle - as a handle is not garbage collected. [/quote] What I'd really like to see is the various dynamic objects OO-ized. Memory issues - gone! OO technology - enabled! 

:) 

Posted by Peter Judge on 10-Jul-2017 09:22

You needn’t bother with the client socket (unless you absolutely must have your own implementations).
 
There are a set of classes for Client Socket support in the OpenEdge.Net.pl - OpenEdge.Net.ServerConnection.ClientSocket and friends ( https://documentation.progress.com/output/oehttpclient/117/OpenEdge.Net.ServerConnection.ClientSocket.html ).
 
 

Posted by Tim Kuehn on 10-Jul-2017 09:34

Cool! I'll look into that.

Posted by Laura Stern on 10-Jul-2017 10:07

And BTW - The doc seems to be all correct on this - Each method correctly indicates what object it can be used on and the doc on SERVER-SOCKET vs. SOCKET IMO clearly indicates what each is used for.  For example, there is a note under SERVER-SOCKET that says: "The server socket object is used to enable the AVM to listen to and accept new connections from socket clients; it is via the socket object that clients and servers communicate"

You're problem seems to have been that what you were reading didn't jive with your a priori conceptions so you didn't trust what it said!  :-)

Posted by Tim Kuehn on 10-Jul-2017 11:02

Laura - I'd note that 13 years ago I spent ~2 months sorting through the socket docs to get a communications protocol working under 9.1, and while I was able to get something working and in production, it had data-loss issues at higher throughput that I couldn't resolve. Even today it seems there've been details I've missed - like when I'm in the READ-RESPONSE routine that SELF points to an endpoint socket object and not the server socket object. 

Was it my fault for failing to "get" that rather critical piece of information after 2 months of work? Or PSC doc's for failing to make it completely clear that an operational system had both a server and an endpoint socket? 

Had "socket object" been termed a "socket endpoint object" and the statement edited accordingly - 

it is via the socket endpoint object that clients and servers communicate

The difference / distinction between the two would've been a lot clearer. 

Re: the data loss issue - I later learned that I needed to set hserversocket:SENSITIVE to FALSE in the READ-RESPONSE code...something I can't recall ever seeing in the docs. Also, back when I was first wrestling with this there wasn't even any demo code around to look at - the community had to figure all this out for themselves.

Posted by Tim Kuehn on 10-Jul-2017 11:56

In addition - the socket KBs need to link to these classes - not much point in writing your own if something else already is out there.

Posted by lecuyer on 10-Jul-2017 12:03

In some ways, I think that the language distinction between "socket" and "server socket" is part of the confusion.  I'm guessing that this distinction derives, in part, from the way that tcp network implementations are expressed in object models.  The ABL concept (although handle based) is consistent with the way sockets are done in Java (and probably in many other languages as well).  However, if you look at the C implementation of TCP, there really isn't much a difference.  When you can create a socket, its "type" (client or server) is based the way it is used, with the distinction being mainly in how the connection is made with the remote peer.  However, once connected, a socket is a socket.  In some ways, it's harder to see the difference, but in other ways, simpler.  Just my $.02.

Posted by Peter Judge on 10-Jul-2017 12:04

That’s a good point – I don’t  know in general terms what we do when kbases go ‘stale’.

Posted by gus bjorklund on 10-Jul-2017 15:44

> On Jul 10, 2017, at 1:05 PM, Peter Judge wrote:

>

> I don’t know in general terms what we do when kbases go ‘stale’.

nothing

This thread is closed