Use 127.0.0.1/5080 to use it!
Press Click me:
Go back and write my name George Karras to search frame:
Press enter:
You can choose to not use the favicon, the icon - it is a png file loaded from popup menu - scroll it down - and converted to base64, so the Binary {} as name1 make a buffer name1 with actrual bytes, so name1(0) is the real adderss of data and len(name1) is the lenght of bytes, which we have to send to client using the send method of socket.
There is a limit of 100 concurrent sockets (way too much). Change to 1 to see what happen. Normally Chrome open and close the connection quick but if we open firefox we can open two pages (not connected to socket) and we can push reload to each quick to get the fault "503 Service Unavailable".
So there are max 100 sockets which we can keep open. Each time one close we push the id to a stack, so each time we want a "free" socket first we see if stack isn't empty and pop from there or we get from the top index to array.
As you see, M2000 Interpreter create 100 sockets wich never get out from array, and if we use it in the OnAccept event of Serversck (Server socket which listen), we assign the outer call to server which the one on array. When the one of them get an event, this event has the first parameter the id. How this happen? Although the M2000 written using VB 6, which can't use array of objects (only array of controls can be used with the index property), they utilize a dynamic way to make events objects so not only can be used to make an array of objects with events, but also we can resize it (not shown here), to make more objects for the user.
About events.
When an event fired from an object search for a function with the name of the object, the underscore and the name of the event. If not find it place it in an exclude list, to skip more calls. When the event fire, we get a call to service function. So that call can send parameters (but for arrays send the index of the object). Also some parameters maybe passed by reference (always send the same way for same event). We can use the Stack statement which show the stack without use it to get the values. All variables which passed by reference have a string in stack. That string used by the Read statement with a & symbol before the new name which will be the reference. The string has the absolute name of a variable which M2000 make for the specific event. So we get a reference, and we can change the value and at the end of the call, M2000 provide this value to the actual caller, which wait to get the value. So events which need to get values back (by reference) have to service them quick. This example has no use of by reference parameters through events.
Calling the function for event we have a new stack (with anything the event send) and the code executed in the name space when the object created, so the same name space for the function which we use, and this is the module which we define the objects. Anything we make new (or local using Local, or global using Global) in the event service function erased at the return. Because some other events may fired before the current terminate we always use the new for read (read new) and as you see everywhere. So if another event run, interrupts the current thread, execute the code, shadowing the same named variables, then return erasing all the new variables, and the older event continue to execute, with no problem. If we want to call a sub it is better to use a module and use the Call Local which is the "cascade" call from an event service function. The call local has the same stack as one from the caller and the same namespace as the one of the caller, and finally at the exit delete everything new - so we can also make local variables.
Αν δεν υπάρχουν δυο μόνιτορ τότε το παρακάτω μικρό πρόγραμμα φτιάχνει ένα μικρότερο παράθυρο, στο οποίο θα εμφανιστεί το κύριο πρόγραμμα (το οποίο απλά δείχνει την κατάσταση του server)
window 12, 12000, 8000
a=(pos.x, pos.y)
a+=1000
(x,y)=a
motion.w x, y
Το πρόγραμμα (τερματίζει με το πλήκτρο Esc). Για να το χρησιμοποιήσουμε ακολουθούμε τις οδηγίες στις εικόνες παραπάνω!
Module Server1 {
binary {
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACWklEQVR4AZRT3UtT
YRj/vYcxWLhd5LQb1xY00i6aUwfhVLof1U1RhC6vRPpYV5G4VqcivLCvgeCfYFNk
fUAX3djHpdsomJs5dqYQRRcmtBuX67w9zzt2AgvC8T7v+/y+nr2cs2nY9Vn+uHok
UzSSVMVMoVxTVTSKhJOs7bLDGqDrupYtlnXYbHlIGaPqJLNdlZSdhGOssYe9xKtl
DYicjc5KidtCCJtS/rGxxp7IuehsU1YDlgvGiBByrEn+7xRSjuUowz5taUnaBOR9
BnspkzKc1VoOGCdM0/ToiUnELo1jITWHn7XaX7NqxM0/nVMePREHZzirCYFQvV5H
xTCwtfUdL56lcffOLVSrVWsI9/f0BF4+TytPxSiDM5zVBMR+u92OQLDHCmxUKphJ
PqYHL1XNPHmEjfV1Sw/29IIznNXI8pWVkegoWlqc3KoqrOTxIZdFLptBobCiON6c
TheGL45yC85q2NFeEZJt7e2YiCfQ2uom2Fil0hpKa58agHbWbsRvwu1uI0R5ymp9
xw6tSiDNjNfnw9T0A5y/MIzwwBD6BwYRHhxCmE7mpqYfwuv1sRWc4az6HfzaMa/R
dTZZcTj2IXLyFMYvX0FHhwcez0HqryrO4XCwhcJykzMM1IDjAf9nCHmGiG0qtd6/
ewujXIZBT5x7RTa2bfaqDGE1gE6EuvxvIMzTdDX1/pxOJxYXUlicT8HlcrGFvhlV
9iivYvDnz8S4r8v/GpD9Aih002u9PjEJrkB3EMyx1vCwu1HWDRoQCB09nP/xTeuV
0oxT4AsX98yx1vQ1z98AAAD//zbMFRIAAAAGSURBVAMA8iAJqkWBAh0AAAAASUVO
RK5CYII=
} as favicon
locale 1033
form 100, 50
Flush
Escape Off
declare withevents Serversck SOCKET
Method Serversck, "create", SocketPort:=5080, SocketAddress:="localhost" as Ok
? ok
Method Serversck, "Listen" as ok
? ok
String sAddr
Long lPort
Method Serversck, "GetSockName", &sAddr, &lPort as ok
If Ok Then
? sAddr
? lPort
end if
Function Serversck_OnError {
stack
}
max_connections=100
connections=0
declare withevents c(max_connections) Socket
ret=stack
long id=0
Boolean Use_Favicon = true
Function Serversck_OnAccept {
local ok as boolean
if len(ret)>0 then
stack ret {
read new id
}
method Serversck, "Accept", c(id) as ok
if ok then print "New User "+id:connections++
else.if id<max_connections then
method Serversck, "Accept", c(id) as ok
If ok then
print "New User "+id
id++
connections++
end if
else
declare local c socket
method Serversck, "Accept", c as ok
if ok then
resp$={HTTP/1.1 503 Service Unavailable
Retry-After: 3600
Content-Type: text/html
Content-Length: #
Connection: keep-alive
}
txt$={<html>
<head><title>503 Service Unavailable</title></head>
<body>
<h1>Service Unavailable</h1>
<p>The server is currently unable to handle the request due to a temporary overload.</p>
</body>
</html>
}
resp$=replace$( "#", str$(Len(string$(txt$ as UTF8enc))*2,""), resp$)+{
}+txt$
// print #-2, resp$
method c, "SendText", resp$ as new ok
? ok
method c,"close_"
end if
end if
}
// modules called from event service fucntions
module alfa (new s$) {
local txt$={<html>
<head><title>Bravo @</title>
<style>div {text-align: center;}</style>
</head>
<body>
<h1>Renspose to @</h1>
<p>bla bla bla</p>
<div><button type="button" onclick="location.href='/'">Go Back</button></div>
</body>
</html>
}
txt$=replace$( "@", s$, txt$)
resp$=replace$( "#", str$(Len(string$(txt$ as UTF8enc))*2,""), resp$)+{
}+txt$
method c(id), "Sendtext", resp$ as new ok
? ">>>>>>>>>>>>> ok"
}
module mainpage {
local txt$={<!DOCTYPE html>
<html>
<body>
<head>
<title>M2000 Html Server1</title>
<style>
div {text-align: center;}
</style>
</head>
<h1>My First Heading</h1>
<p>My first paragraph.</p>
<p>Ελληνικά γράμματα</p>
<search>
<form>
<input name="something" id="something" placeholder="Search Server1">
</form>
</search>
<div>
<svg width="100" height="100">
<circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
Sorry, your browser does not support inline SVG.
</svg>
</div>
<div><button type="button" onclick="location.href='/alfa.html'">Click Me!</button></div>
###
</body>
</html>
}
txt$=replace$("###",date$(today, "long Date")+", "+time$(now,"Long Time"), txt$)
local resp$={HTTP/1.1 200 OK
Cache-Control: no-store
Content-Type: text/html; charset=UTF-8
Content-Length: #
Connection: keep-alive
}
resp$=replace$( "#", str$(Len(string$(txt$ as UTF8enc))*2,""), resp$)+{
}+txt$
//print #-2, resp$
method c(id), "SendText", resp$ as new ok
? ok
}
function c_OnReceive (new id){
Print "OnReceive "+id
method c(id), "ReceiveText" as new txt$
Print #-2, txt$
if left$(txt$, 14) = "GET / HTTP/1.1" then
call local mainpage
else.if Ucase$(left$(txt$, 16)) = "GET /?SOMETHING=" then
local search$=string$(filter$(leftpart$(mid$(txt$, 17), " "), "@") as URLdec +)
local resp$={HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: #
Location: http://127.0.0.1:5080/alfa.html
}
call local alfa, search$
else.if UCASE$(left$(txt$, 15)) = "GET /ALFA.HTML " then
local resp$={HTTP/1.1 200 OK
Cache-Control: no-store
Content-Type: text/html; charset=UTF-8
Content-Length: #
Connection: keep-alive
}
call local alfa, "You"
else.if UCASE$(left$(txt$, 25)) = "GET /FAVICON.ICO HTTP/1.1" then
if Use_Favicon then
Print "Favicon..."
local resp$={HTTP/1.1 201 OK
Content-Type: image/png
Content-Length: #
Cache-Control: public, max-age=31536000
}
resp$=replace$( "#", str$(Len( favicon),""), resp$)
method c(id), "Sendtext", resp$ as new ok
method c(id), "Send", favicon(0), len(favicon) as new total_send
? total_send, Len(favicon)
? "connections = ";connections
else
local resp$={
HTTP/1.1 204 No Content
Cache-Control: public, max-age=31536000
}
method c(id), "Sendtext", resp$ as new ok
end if
end if
}
function c_OnClose(new id) {
method c(id), "Close_"
stack ret {push id}
Print "close "+id
connections--
Print "opened connections: ";connections
Print Ret
refresh
}
function c_OnError(new id, erNum, mask) {
Print "Error "+id
Hex erNum
method c(id), "GetErrorDescription",erNum as new ret$
Print "Description: "; ret$
Print "Mask "+mask
}
do
if keypress(27) then exit
refresh
wait 100
always
declare Serversck nothing
Escape on
}
Server1



