You are not logged in.
Thanks ab, so I'm trying THttpClientWebSockets, according your latest reply it seems that I'm not using the correct class, so will try TWebSocketServer now...
You can ignore my current testing result: using THttpClientWebSockets:
var
myStr: string;
begin
if Assigned(FWSCli) then
FWSCli.Free;
//FWSCli := TSQLHttpClientWebsockets.Create(cSvrAddr, cCefDebugPort, TSQLModel.Create([])); //same error.
FWSCli := THttpClientWebSockets.Open(cSvrAddr, cCefDebugPort);
FWSCli.Settings.SetFullLog;
myStr := FWSCli.WebSocketsUpgrade('ws://localhost:9289/someUri', '', True, True);
LogIt('WebSocketsUpgrade result: ' + myStr);Result:
WebSocketsUpgrade result: Invalid HTTP Upgrade HeaderHi ab,
I need to communicate with the Chrome browser via WebSockets: https://developer.chrome.com/devtools/d … r-protocol
Hi Arnaud,
I'm new to WebSockets and I'm lost in the great amount of classes defined in SynBidirSock.pas ![]()
I want to do something using the client class like the following (taken from https://github.com/andremussche/DelphiWebsockets):
client := TIdHTTPWebsocketClient.Create(Self);
client.Port := 12345;
client.Host := 'localhost';
client.SocketIOCompatible := True;
client.SocketIO.OnEvent(C_SERVER_EVENT,
procedure(const ASocket: ISocketIOContext; const aArgument: TSuperArray; const aCallback: ISocketIOCallback)
begin
ShowMessageInMainthread('Data PUSHED from server: ' + aArgument[0].AsJSon);
//server wants a response?
if aCallback <> nil then
aCallback.SendResponse('thank for the push!');
end);
client.Connect;
client.SocketIO.Emit(C_CLIENT_EVENT, SO([ 'request', 'some data']),
//provide callback
procedure(const ASocket: ISocketIOContext; const aJSON: ISuperObject; const aCallback: ISocketIOCallback)
begin
//show response (threadsafe)
ShowMessageInMainthread('RESPONSE: ' + aJSON.AsJSon);
end);Which class in the mORMot framework I should use? I guess its
THttpClientWebSockets?
And How to send and receive JSON data? Thanks.
IIRC, it's announced few years ago, I don't think it's under active development tough.
To me, with the recent JSON support added to sqlite3, it's almost perfect in my use cases so far ![]()
Yes, we got rid of those %s %d %g details, which were more misleading and source of error at runtime...
That's s good, error-tolerable design, well done!
@ab, sorry, I thought FormatUTF8() is a *complete* counterpart of Format() and I used "%d", and just found this comment in the source code:
// only supported token is %, with any const argumentsI guess so ![]()
Hi Arnaud,
A bug report.
The FormatUTF8() function defined in SynCommoms.pas cannot handle large int64 values such as 2119852951849248647
I'm using the latest rev. from github.com
Upate 1: Obviously I'm using this function in a wrong way - I thought it supports all types of arguments as supported by Format(), but actually it supports the "%" argument only.
Is linux support there?
I think there is no ready-made methods of doing this.
Sorry, I misread your post and I thought you were talking about auto-reloading without refreshing the browser. AB has given you the correct answer.
@ab, Updated the mORMot framework and added StringReplaceAll to the benchmark test, here is the result:
Standard StringReplace(): 0.2340 secs
StringReplace1: 0.1250 secs
StringReplace2: 0.1090 secs
StringReplace3: 1.7160 secs
StringReplace4: 0.0780 secs
FastStringReplace: 0.0470 secs
ReplaceStr: 0.2500 secs
ReplaceText: 0.3430 secs
StringReplaceAll - Implict to UTF8: 0.1250 secs
StringReplaceAll - EXplict to UTF8: 0.0620 secs
The winner is: FastStringReplace
------------------------------------------------------------New finding: Use of StringToUTF8 can really improve the performance ![]()
@ab, actually I was thinking of using WebSockets too, I'll give it a try next ! ![]()
Some of my experiments shows that using HTTP as the communication channel is preferred than Named Pipe or Winapi messaging, even your scenario is same-machine inter-process architecture, for the following reasons:
- Establishing a named pipe connection is much slower.
- Using named pipe will become unstable very quickly as your program runs.
- Using Windows messaging can easily lead to dead-locking.
I guess this because people mostly use the http channel and seldom use named pipe or win messaging, so problems and bugs related to those two communication channels were not being found, reported nor fixed...
@itSDS, Very nice finding and thanks for sharing!
I added to items to the benchmark list, it's ReplaceStr and ReplaceText.
Test results on my computer:
Standard StringReplace(): 0.2180 secs
StringReplace1: 0.1250 secs
StringReplace2: 0.1090 secs
StringReplace3: 1.7630 secs
StringReplace4: 0.0780 secs
FastStringReplace: 0.0310 secs
ReplaceStr: 0.2340 secs
ReplaceText: 0.3430 secs
The winner is: FastStringReplace
------------------------------------------------------------Sounds like a good news ![]()
Not sure I understand you, but the mORMot is fundamentally based on the RESTful concept.
@ab, a feature request I can create, a patch is currently beyond my level of understanding into this framework ![]()
Hi ab,
I've got a log error emitted by the server (I use named pipe channel):
20160106 18195731 EXC EORMBatchException ("TMyServer.EngineBatchSend: Wrong SIMPLE") at 0077D6E6 mORMot.TSQLRestServer.EngineBatchSend (38629) stack trace API In what cases this might happen? Thanks.
In this use case of mine it's not a ERP-type of business application, it's desktop app inter-process senario, so cross-db and security is not a concern ![]()
Hi Arnaud,
I can see the advantages (both performance and avoid strange dead-locks) of the BatchStart/BatchSend serious of methods.
Currently the batch operations are limited to record addition, update and deletion only, is it possible to also add a new method which works like Execute(aSql: utf8string) but is handled by the batch mechanism? Thanks.
@AOG, that must be very helpful for people who want to consume a mORMot-powered REST server from inside the browser using JS!
BTW, you must have chosen OpenUI5 for good reasons, care to tell us briefly about why you have chosen it over other html frontend frameworks? Thanks in advance.
Another web frontend framework that might be of interesting is VCL.JS - it's based on TypeScript (a language which is very similar to Delphi created by the same creator of Delphi), and it mimics the VCL's conception for component encapsulation based for the most popular html framework Twitter BootStrap.
Thanks for sharing!
Agreed! start from the supplied samples (over 30 samples!) and it's very very easy to understand.
Hi AArhin,
This might be of helpful: https://tamingthemormot.wordpress.com/
Aside from that, I'm afraid at this moment you'll have to bear with this fact ![]()
@warleyalex, you are fast! And it also proves that Framework7 is easy to use while powerful ![]()
@ab, I inferred the github repository of warleyalex's example: https://github.com/smartpascal/smartms
The best html5 based mobile web UI framework I found so far: http://www.idangero.us/framework7/
Smart Mobile Studio is cool and I love the Object Pascal language, but I wouldn't use SMS because it's not well-documented the last time I checked. On the hand, if you use JavaScript you'll find that you can find ready-to-use solutions and documents for every single problem you might encounter.
Hi ab,
I'm really sorry, after spent hours of checking, it turned out to be a logical bug in my program but not a problem of the mORMot frame itself. I will update the original topic above.
@mpv, thanks for your comments. I'm curious, the implicit conversion is slow when compared to using functions in SynCommons, because of the internal RTL functions used to perform the implicit conversion is not optimized, right?
ab, what connection properties do you mean? The TSQLRestClientURI in question is already working with other type of 'select' statements...
update: It turned out to be a logical bug in my program but not a problem of the mORMot framework. I'm sorry.
Hi Arnaud,
The code:
var
tmpTable: TSQLTableJSON;
begin
tmpTable := aDb.ExecuteList([], aSql);
end
I found that TSQLRestClientURI.Execute() returns zero rows for this SQL:
SELECT CurrentStock FROM v_Inventory WHERE (ID = 12345)It returns zero row, but I use Sqlite Studio and it should return one row. What might be wrong?
Thanks.
Never tried 'Tsql', but you can just try it ('CreateMisingTables') and see the result immediately.
Hi,
It seems to be working well, but I'm still not 100% sure about it - is it safe to use implicit RawUTF8 <-> string conversion in unicode Delphi (version after 2009)?
I mean:
- directly pass values of type 'String/UnicodeString' to mORMot functions that expect type 'RawUTF8', eg:
var
mystr: string;
begin
myDb.ExecuteList([], myStr);
end;- Directly assigning RawUTF8 to String, eg:
var
myUtf8: RawUTF8;
begin
TEdit.Text := myUtf8;
end;I don't think it's possible with the current version of mORMot. mORMot can automatically create and update database schema from the TSQL-prefixed class models, but not the other way around.
@mvp, that sounds exciting! How much node.js module we'll be able to use with that addition?
Hi Arnaud,
If you want to use fts5, you should compile the sqlitefts3.obj using the free c++ builder command line tool, right?
Quoting from the sqlite.org website: "The fts4aux module is automatically included in all builds that include FTS." I'm not sure if it's the same case with mORMot.
Hi Arnaud, You are always fast!
Passing such big numbers in JSON is not good solution IMHO. In case your service is used from browser it will lose precision during json.parse. Internally in JavaScript numbers are double. In my services I either limit a int64 values to 10^16 or pass it as string if limitation is not possible
Thanks MPV, I'm not using it in the browser, but that seems a limit of JS, is there a way to get around it, like treating the IDs as strings?
It is error prone only if you do not use the ORM, but SQL and TDataSet...
Yes, but I guess it's very common to use SQL directly for complex reports that require multiple level of joins even union joins.
Great! Just noticed that the the json1 JSON extension has been integrated into sqlite 3.9.0 official release!
PS, there is a new 3.9.1 which includes a critical fix for a bug related to the newly added JSON features: https://www.sqlite.org/src/info/57eec374ae1d0a1d
@sag2007, thanks for sharing, very helpful.
@mpv, PS, looks like http://duktape.org/ is much simple and easy to make a wrapper, and I'm quite sure SpyderMonkey is much full-featured ![]()
I guess a workaround would be making a wrapper function around TStaff.FilterStaff() which accepts json string instead, But definitely it's perfect if @ab can fix it.
Thanks @Nouba, good to know that!
Thanks for the explanation, ab.
I understand it that the REST server (which can be accessed remotely) should not allow multiple SQL execution at a time, but if I'm correct, at the database engine level (which for local access), this function should be exposed.
PS, it's extremely useful when upgrading an existing database if one can execute multi sql statements at a time, for example, execute a bunch of SQLs from a .sql file extracted from a db management tool.
Hi ab,
By nature many DBMS including the SQLITE3 engine supports executing multiple SQL statements delimited by commas, but it seems that both the TSQLRestServer and TSQLDBConnectionProperties do not support comma-separated SQL statements?
Thanks.
Hi Arnaud,
Yes, I can solve the problem that way. But I still tend to think the ExecuteList() should either correctly determine all field types or the user have to manually set type for all fields, otherwise it's error-prone.