View previous topic :: View next topic |
Author |
Message |
rajvasan Beginner
Joined: 10 Dec 2002 Posts: 14 Topics: 4
|
Posted: Fri Dec 20, 2002 1:00 am Post subject: MVS Chat |
|
|
Dear All,
I have created a Server , Client program in the mainframe. The server when running, can accept multiple clients. But I have a problem as to how to keep track of all the threads from the server that are running with each client. Actually, I wanted of developing something like a yahoo chat in the mainframe, but im stuck now at this point. One more thing is that , can we dynamically add text to a panel.
Expecting your responses..
With Best Regards,
Rajvasan |
|
Back to top |
|
|
Dibakar Advanced
Joined: 02 Dec 2002 Posts: 700 Topics: 63 Location: USA
|
Posted: Tue Dec 31, 2002 6:46 am Post subject: |
|
|
Interesting topic. Why not share the relevant code and see what suggestions you get. |
|
Back to top |
|
|
Cogito-Ergo-Sum Advanced
Joined: 15 Dec 2002 Posts: 637 Topics: 43 Location: Bengaluru, INDIA
|
Posted: Tue Dec 31, 2002 9:15 am Post subject: |
|
|
Raj,
It is really interesting to know that you have undertaken such a bold venture. I would like to voice my opinion.
Are you looking at all the possible variations? That is, one-to-one, one-to-many or many-to-one and many-to-many communications?
Are you using CICS? You know that, a CICS program will execute only when a PF-key is hit. Thus, you would not able to alert a recepeint if a message is sent. The recepeint would have to keep hitting a PF-key continiously to check if some message has been sent. (Of course, if you have something else up your sleeve, then I would not know. ) Won't this apply for an ISPF panel?
In CICS, if you do not want the user to keep hitting a PF-key, then maybe you have to use STI (Scheduled Task Inititiation). I do not know, if this is a good idea. But, we cannot have two split screens; one for displaying messages as and when they come and the other for sending your messages.
I am sorry I am not being much of a help. But, I was curious, so I put in my 2 paise!
[/list] _________________ ALL opinions are welcome.
Debugging tip:
When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.
-- Sherlock Holmes. |
|
Back to top |
|
|
rajvasan Beginner
Joined: 10 Dec 2002 Posts: 14 Topics: 4
|
Posted: Fri Jan 03, 2003 2:48 am Post subject: |
|
|
Dear all,
Thanks for your replies. Cogito,as you had mentioned, we need to hit a PF key to see whether any new message has come(im not using CICS). Also, Im trying to take care of all the combinations. Iam still working on it(when I find time). In the meanwhile, if any of you can get any light, please share with me. It would be of great help to me
With Best Regards,
Rajvasan
P. S : Does anybody have any idea as to how to maintain separate threads(one for each client) |
|
Back to top |
|
|
semigeezer Supermod
Joined: 03 Jan 2003 Posts: 1014 Topics: 13 Location: Atlantis
|
Posted: Fri Jan 03, 2003 4:22 am Post subject: |
|
|
It depends what mechanism you are using for communication and for display. There are lots of methods I can think of to do the communication (shared data space, shared file, CSA storage, cross memory, etc). For display, you can use ISPF or do your own screen I/O. You didn't specify how it is being done, but I assume you mean 3270 output and only local clients.
My 1st thought would be that you create a controlling task as a started task that simply manages the data (the chat log). I don't think there is any need for it to have user tasks because if the client programs can query the shared data they can monitor and format it themselves. You just need to define appropriate read and write mechanisms to get at the log data. If you use a shared data space, then you don't even need to do that. The authorized started task creates the data space and everyone else just reads and writes to it, with appropriate serialization, of course.
And if you need multiple chat logs, you just create multiple data spaces and probably one that acts as a directory of the others.
If you don't use ISPF, you may be able to do unsolicited writes to the screen by writing your own 3270 data streams so you would need a monitoring subtask created via ATTACH. Even with ISPF that might be possible, but probably not.
In any event, the best presentation mechanism for this if you are using ISPF is to use a dynamic area. You could use the ISPF BRIF service but there are some complications doing that. |
|
Back to top |
|
|
semigeezer Supermod
Joined: 03 Jan 2003 Posts: 1014 Topics: 13 Location: Atlantis
|
Posted: Fri Jan 03, 2003 11:07 pm Post subject: |
|
|
The last time I used a data space it had to be done in assembler. Maybe the high level languages handle it now, I don't know. But basically, all that would happen is that a central address space, a started task probably, creates a shared data space and then clients using TSO terminals could read and write to it. With some fancy programming on the client side, you could wait on changes in the dataspace and update the screen accordingly. There are other ways to do it too of course. The data space just seemed good to me at the time. A shared file would be easiest, but I have a feeling that having everyone open and close it so often would cause it to run out of extents very quickly (assuming they opened DISP=MOD and just wrote) |
|
Back to top |
|
|
semigeezer Supermod
Joined: 03 Jan 2003 Posts: 1014 Topics: 13 Location: Atlantis
|
Posted: Sat Jan 04, 2003 1:05 am Post subject: |
|
|
Since my last post, I got to thinking about how to do a really simple chat... let the ISPF editor do the updates. It has built in serialization. Ok, the performance is terrible, but it works. I threw together a working sample. For the sake of brevity, I'll leave it as an exercise to the reader on having multiple concurrent chats, real error handling etc, but that stuff is pretty trivial. Listing who is in the chat can be done with the QUERYENQ service on SYSDSN and the chat data set name. Scrolling should be relatively easy too.
3 parts: 1 panel (CHATPAN), 1 Rexx (CHAT) and 1 ISPF edit macro (CHATMAC)
Panel CHATPAN Code: | )ATTR
@ AREA(DYNAMIC) EXTEND(ON)
01 TYPE(DATAOUT) INTENS(LOW) COLOR(BLUE)
02 TYPE(DATAOUT) INTENS(HIGH) COLOR(YELLOW)
+ type(NT)
_ type(NEF)
)BODY CMD()
%-------------------------- A Simple MVS Chat ---------------------------------%
+Chat name:%&CHATNAME %
%Message ===>_MSG %
%.-----------------------------------------------------------------------------.
%|+@VIEW @%|
%|+@ @%|
%'-----------------------------------------------------------------------------'
)PROC
&VIEWSIZE = LVLINE(VIEW)
)END |
Edit macro CHATMAC:
Code: | ISREDIT MACRO
ISPEXEC VGET MSGX SHARED
ISREDIT NUM OFF
ISREDIT CAPS OFF
ISREDIT LINE_AFTER .ZLAST = (MSGX)
ISREDIT SAVE
ISREDIT END |
And the short driver Rexx CHAT Code: | /* Rexx - A dumb MVS chat program */
chatdsn= '''SOME.CHAT.DATASET'''
chatname = 'A sample chat session'
Call syscalls 'ON'
Call msg 'OFF' /* 1st one in creates data set */
'ALLOC F(CHAT) DA('chatdsn') DSORG(PS) LRECL(80) RECFM(F B) NEW CAT ',
'SPACE(10,100) TRACK REUSE'
'FREE F(CHAT)'
'ALLOC F(CHAT) DA('chatdsn') SHR' /* It should exist now */
/* Set up for eventual edit, then get screen size */
Address ispexec 'LMINIT DATAID(CHATID) DDNAME(CHAT) ENQ(SHR)'
Address ispexec 'PQUERY PANEL(CHATPAN) AREANAME(VIEW) DEPTH(VIEWSIZE)'
Address ispexec 'CONTROL ERRORS RETURN'
Address ispexec 'VGET ZSPLIT' ; if zsplit = 'YES' then exit
/* now loop and update as needed */
msg=''
Do Until disprc>0
'EXECIO * DISKR CHAT (FINIS STEM DATA.'
lines=min(data.0,viewsize) /* Line # Of lines to show */
top=max(data.0-viewsize+1,1) /* get data # of top line */
view=''
Do a=1 to lines
view=view||left(data.top,75)
top=top+1
End
Address ispexec 'DISPLAY PANEL(CHATPAN)'
disprc=rc
If disprc=0 & msg \= '' Then
Do
msgx='01'x||left(userid(),7)||'02'x||msg
Address ispexec 'VPUT (MSGX) SHARED'
Do 10 Until editrc = 0
Address ispexec 'EDIT DATAID(&CHATID) MACRO(%CHATMAC)'
editrc=rc
If editrc = 14 Then Address syscall 'SLEEP 1'
End
If editrc=0 Then msg=''
Else Say 'Message was not added to the log. Please try again.'
Address ispexec 'VERASE (MSGX) SHARED'
End
End
Address ispexec 'LMFREE DATAID(&CHATID)'
'FREE F(CHAT)'
'ALLOC F(CHAT) DA('chatdsn') OLD DEL REUSE'
'FREE F(CHAT)' /* last one out deletes data set */ |
I also have a much faster version that doesn't use the editor and uses ISPF tables for synchronization if anyone wants it. |
|
Back to top |
|
|
DaveyC Moderator
Joined: 02 Dec 2002 Posts: 151 Topics: 3 Location: Perth, Western Australia
|
Posted: Tue Jan 07, 2003 8:02 am Post subject: |
|
|
Hats off to semigeezer for a blinding name and a good piece of code. It's funny, a persons code is like a signature, I've seen that style before...
I wouldn't mind a copy of your ISPF table version.
The only thing I would do differently is to use constants in the REXX for readability
Code: |
ATTR_BLUE = x'01'
ATTR_YELLOW = x'02'
|
_________________ Dave Crayford |
|
Back to top |
|
|
semigeezer Supermod
Joined: 03 Jan 2003 Posts: 1014 Topics: 13 Location: Atlantis
|
Posted: Wed Jan 08, 2003 12:40 pm Post subject: |
|
|
OK. But I got a little carried away playing with it. It has grown to about 200 lines so I put it in a zip file. It now requires the QueryENQ program because the QUERYENQ service in ISPF is apparently buggy.
It adds a few things I just felt like playing with so I suppose it could be used as a sample for:
- Using Tables as an ENQ mechanism
- Using dynamic areas for display (it doesn't scroll right now)
- Using graphic escape characters to draw pretty lines and boxes
- Using ENQs to determine who has a data set
- Finding the 1st ddname associated with an allocated data set.
- Managing multiple accesses to an application that would otherwise use fixed ddnames.
It is still uncommented ugly code because it is just a toy, but it works. I doubt there is a great need for chat on MVS, especially since you can't do unsolicited screen updates easily. Anyway, I tested it with 4 simultaneous users. |
|
Back to top |
|
|
DaveyC Moderator
Joined: 02 Dec 2002 Posts: 151 Topics: 3 Location: Perth, Western Australia
|
Posted: Wed Jan 08, 2003 10:47 pm Post subject: |
|
|
That's fantastic, I have been looking for a REXX swareq function for ages.
I don't consider uncommented code to be ugly. In HLLs I detest lots of verbose comments. I prefer comments at the start of a block of code, variable declarations and for work arounds. Too many comments can make a program difficult to read and hard to maintain... _________________ Dave Crayford
Last edited by DaveyC on Wed Jan 08, 2003 10:58 pm; edited 1 time in total |
|
Back to top |
|
|
semigeezer Supermod
Joined: 03 Jan 2003 Posts: 1014 Topics: 13 Location: Atlantis
|
Posted: Wed Jan 08, 2003 10:54 pm Post subject: |
|
|
Credit for the SWAREQ piece goes to Gilbert Saint-flour. |
|
Back to top |
|
|
coolman Intermediate
Joined: 03 Jan 2003 Posts: 283 Topics: 27 Location: US
|
Posted: Thu Jan 09, 2003 4:39 am Post subject: |
|
|
Semigeezer.
Thanks a lot for your wonderful effort. Right now, Im able to understand the code in bits and pieces. It would be really great if someone of you could explain the flow part of it as well as some terms like QueryEnq, swareq etc..(and probably the manuals also for these terms).
Thanks
________
I-Active Valve Lift System
Last edited by coolman on Sat Feb 05, 2011 1:16 am; edited 1 time in total |
|
Back to top |
|
|
DaveyC Moderator
Joined: 02 Dec 2002 Posts: 151 Topics: 3 Location: Perth, Western Australia
|
Posted: Thu Jan 09, 2003 7:34 am Post subject: |
|
|
Hat's off to GSF. It just goes to show that a 15 line piece of code can be just as useful as an application. SWAREQ is an assembler macro that resolves SVA (virtual addresses for the SWA - Scheduler Diagnostic Work Area). If they reside below the line they are real addresses, otherwise they are tokens. GSF must have disassembled the code or maybe just worked it out into a REXX. That piece of code has saved me a lot of effort.
The one problem I've always had with using tables for serialization is that the TBCLOSE does not close the file associated with the LIBRARY. It's a pain because I cannot free the allocation. I suppose that's what QUERYENQ was supposed to fix. The only reason I can imagine it works like this is just in case you want to open the table again. Otherwise, I would say it's a bug... Anybody know a way around this? _________________ Dave Crayford |
|
Back to top |
|
|
semigeezer Supermod
Joined: 03 Jan 2003 Posts: 1014 Topics: 13 Location: Atlantis
|
Posted: Thu Jan 09, 2003 1:27 pm Post subject: |
|
|
Check the code in the link. The trick is to do a TBOPEN on a nonexistant library. That way ISPF closes the 1st one before attempting to do open the 2nd (dummy one). |
|
Back to top |
|
|
DaveyC Moderator
Joined: 02 Dec 2002 Posts: 151 Topics: 3 Location: Perth, Western Australia
|
Posted: Thu Jan 09, 2003 8:13 pm Post subject: |
|
|
Cheers mate, it works a treat. I can't use QUERYENQ because it's ISPF V5 and we need to support version 4. But that super neat little trick is going to go straight into our products... _________________ Dave Crayford |
|
Back to top |
|
|
|
|