Welcome, Guest |
You have to register before you can post on our site.
|
Online Users |
There are currently 216 online users. » 1 Member(s) | 212 Guest(s) Bing, Google, Yandex, Ibouka
|
Latest Threads |
IWjQGrid get value from G...
Forum: IntraWeb General Discussion
Last Post: medzoom
Yesterday, 03:58 PM
» Replies: 2
» Views: 188
|
IntraWeb 15.5.9 is out!
Forum: IntraWeb General Discussion
Last Post: jeroen.rottink
03-15-2024, 09:53 AM
» Replies: 6
» Views: 564
|
Multipage websocket commu...
Forum: IntraWeb General Discussion
Last Post: zsleo
03-14-2024, 09:30 PM
» Replies: 1
» Views: 243
|
Closing a TCP/IP componen...
Forum: Indy General Discussion
Last Post: rlebeau
03-14-2024, 04:39 PM
» Replies: 3
» Views: 286
|
Support wwwroot and templ...
Forum: IntraWeb General Discussion
Last Post: ccy
03-13-2024, 10:21 AM
» Replies: 0
» Views: 138
|
can't reach Website after...
Forum: IntraWeb General Discussion
Last Post: bjoernb
03-13-2024, 10:16 AM
» Replies: 1
» Views: 222
|
Please support THandlers....
Forum: IntraWeb General Discussion
Last Post: ccy
03-13-2024, 10:14 AM
» Replies: 0
» Views: 127
|
session timeout thread
Forum: IntraWeb General Discussion
Last Post: ebob42
03-12-2024, 11:46 AM
» Replies: 0
» Views: 140
|
Data Decimation in ChartJ...
Forum: IntraWeb General Discussion
Last Post: Alexandre Machado
03-11-2024, 06:37 AM
» Replies: 7
» Views: 695
|
TIWEdit format mask
Forum: IntraWeb General Discussion
Last Post: troberts
03-10-2024, 11:59 PM
» Replies: 4
» Views: 512
|
|
|
IWjQGrid get value from Grid |
Posted by: medzoom - 03-15-2024, 02:01 PM - Forum: IntraWeb General Discussion
- Replies (2)
|
|
I didnt find a solution in the demo-file, but how do I read the value of an consisting jQGrid?
I try to react to a doubleClick, first .cell[1,1]-call raises an exception and second .DoGridGetCell(..)-call gives a empty string back?
In the TMS-Sourcecode the is an function .cells but with IntraWeb there isn't?
Code: procedure TIWFrame1.IWjQGrid1AsyncDblClickRow(Sender: TObject;
EventParams: TStringList; const RowID: string; const Row, Col: Integer);
var
text1, text2, text3 : string;
begin
text3 := IWjQGrid1.Columns[1].DisplayName;
text1 := IWjQGrid1.Cell[1,1];
text2 := IWjQGrid1.DoGridGetCell(RowID, 'Column1');
end;
|
|
|
Support wwwroot and templates files from application resources |
Posted by: ccy - 03-13-2024, 10:21 AM - Forum: IntraWeb General Discussion
- No Replies
|
|
When deploy intraweb application using wwwroot and templates, 2 extra folders wwwroot and templates shall deploy to same folder stored the application executable file.
Windows or Delphi application support resources stored in .EXE or .DLL / .BPL, it would be nice if IntraWeb can support loading those files from application resource to avoid deploy extra files at runtime.
I submitted a patch to support loading the templates from TResourceStream for your reference:
Code: unit IWTemplateProcessorHTML.ResourcePatch;
interface
uses
System.Classes, System.SysUtils;
var LoadTemplateEx: TFunc<string, TStream>;
implementation
uses
System.Types,
DDetours, IW.Common.StrLists, IW.Common.Stream, IW.Common.Strings,
IW.Common.Threads, IWFilePath, IWGlobal, IWTemplateProcessorHTML;
type
TIWTemplateCacheAccess = class
private
mFiles: TIWStringList;
mLock: TIWSlimReaderWriter;
end;
TIWTemplateCacheHelper = class helper for TIWTemplateCache
class function FindItem_Address: Pointer;
class function Load_Address: Pointer;
function Load_Patch(const aFileName: string; aRefreshFromFile: Boolean): TStream;
end;
TIWTemplateProcessorHTMLHelper = class helper for TIWTemplateProcessorHTML
function Able_Patch: Boolean;
function TemplatePathname_Patch: string;
end;
var TIWTemplateProcessorHTML_Able: function(Self: TIWTemplateProcessorHTML): Boolean;
var TIWTemplateProcessorHTML_TemplatePathname: function(Self: TIWTemplateProcessorHTML): string;
var TIWTemplateCache_FindItem: function(Self: TIWTemplateCache;
const aFileName: string): TIWTemplateCacheItem = nil;
var TIWTemplateCache_Load: function(Self: TIWTemplateCache;
const aFileName: string; aRefreshFromFile: Boolean): TStream;
class function TIWTemplateCacheHelper.FindItem_Address: Pointer;
begin
Result := @TIWTemplateCache.FindItem;
end;
class function TIWTemplateCacheHelper.Load_Address: Pointer;
begin
Result := @TIWTemplateCache.Load;
end;
function TIWTemplateCacheHelper.Load_Patch(const aFileName: string;
aRefreshFromFile: Boolean): TStream;
var
LStream: TIWMemoryStream;
Item: TIWTemplateCacheItem;
begin
Result := nil;
(* patched: if FileExists(aFilename) then*) begin
(* patched: LStream := TIWMemoryStream.Create;
try
TIWMemoryStream(LStream).LoadFromFile(aFileName);
except
FreeAndNil(LStream);
raise;
end;*)
var sFileName := ExtractFileName(aFileName);
var o := LoadTemplateEx(sFileName);
try
LStream := TIWMemoryStream.CreateCopy(o, 0);
finally
o.Free;
end;
if aRefreshFromFile or not Able then Exit(LStream);
Item := TIWTemplateCacheItem.Create(LStream);
try
// we are going to return a copy of the stream
Result := LStream.Clone;
// the original LStream is going to be stored in our cache
TIWTemplateCacheAccess(Self).mLock.BeginWrite;
try
TIWTemplateCacheAccess(Self).mFiles.AddObject(aFileName, Item); // add the stream to the cache
finally
TIWTemplateCacheAccess(Self).mLock.EndWrite;
end;
except
FreeAndNil(Item);
raise;
end;
end;
end;
function TIWTemplateProcessorHTMLHelper.Able_Patch: Boolean;
begin
(* patched
Result := False;
if Enabled then begin
Result := Assigned(FOnBeforeProcess) or FileExists(TemplatePathname);
end;
*)
Result := True;
end;
function TIWTemplateProcessorHTMLHelper.TemplatePathname_Patch: string;
var
S: string;
begin
if Templates.Default = '' then begin
// This is for subtemplates of regions. Right now containername returns:
// formName.regionName. We rename it to formNameRegionName and that way
// if no name is specified for the templates for regions, it uses this as
// the default one
if Assigned(Container) then begin
// Remove the T from subclass name (AFTER the .)
if (s <> '') and (Pos('.T', UpperCase(s)) > 0) then begin
s := IWStringReplace(UpperCase(Container.ContainerClassName), '.T', '', []);
end;
s := IWStringReplace(Container.ContainerClassName, '.', '', []);
// Remove T from it
if IWStartsText('T', s) then begin
Delete(s, 1, 1);
end;
s := s + '.html';
end else begin
s := '';
end;
(* patched if Assigned(gSC) and FileExists(gSC.TemplateDir + s) then *)begin
FTemplates.Default := s;
end;
end;
if Templates.Default <> '' then begin
Result := Templates.Default;
end;
Result := TFilePath.Concat(gSC.TemplateDir, Result);
end;
initialization
TIWTemplateProcessorHTML_Able := InterceptCreate(@TIWTemplateProcessorHTML.Able, @TIWTemplateProcessorHTML.Able_Patch);
TIWTemplateProcessorHTML_TemplatePathname := InterceptCreate(@TIWTemplateProcessorHTML.TemplatePathname, @TIWTemplateProcessorHTML.TemplatePathname_Patch);
TIWTemplateCache_Load := InterceptCreate(TIWTemplateCache.Load_Address, @TIWTemplateCache.Load_Patch);
finalization
InterceptRemove(@TIWTemplateProcessorHTML_Able);
InterceptRemove(@TIWTemplateProcessorHTML_TemplatePathname);
InterceptRemove(@TIWTemplateCache_Load);
end.
|
|
|
Please support THandlers.Delete method in unit IW.Content.Handlers.pas |
Posted by: ccy - 03-13-2024, 10:14 AM - Forum: IntraWeb General Discussion
- No Replies
|
|
In unit IW.Content.Handlers.pas, THandlers.Add method is available but there is no Delete method to remove TContentBase handler.
It is useful for application deployed with dynamic packages so we can write something like this:
Code: initialization
THandlers.Add('/register/', '', TContent_Register.Create);
finalization
THandlers.Delete('/register/', '');
end.
A patch for reference:
Code: unit IW.Content.Handlers.Patch;
interface
uses
IW.Content.Handlers;
type
THandlersHelper = class helper for THandlers
class procedure Delete(const aPath, aDocument: string);
end;
implementation
uses
System.SysUtils,
IW.Common.Strings, IWServerControllerBase;
class procedure THandlersHelper.Delete(const aPath, aDocument: string);
var i: Integer;
xPath: string;
begin
TIWServerControllerBase.CheckLockGlobal('Handlers.Delete');
if (aPath = '') and (aDocument = '') then begin
raise Exception.Create('Path and Document cannot both be empty.');
end;
// xPath
// -Path + Document: /mypath/mydoc.html
// -Path + Extension: /mypath/*.zat
// -Path: /mypath/
// -Document: mydoc.html
// -Extension: *.zat
if aPath = '' then begin
xPath := aDocument;
end else begin
if not IWStartsText('/', aPath) then begin
raise Exception.Create('Path must start with /');
end else
if (Length(aPath) > 1) and not IWEndsText('/', aPath) then begin // if aPath = '/', StrUtils.EndsText() returns false for EndsText('/', aPath)!!!
raise Exception.Create('Path must end with /');
end;
xPath := aPath + aDocument;
end;
if mList.Find(xPath, i) then
mList.Delete(i);
end;
end.
|
|
|
Closing a TCP/IP component connection the right way |
Posted by: Ahmed Sayed - 03-12-2024, 04:08 PM - Forum: Indy General Discussion
- Replies (3)
|
|
Hi,
Let's say that, I have a TCP component with its connection opened with the server, whether it is TIdTCPClient, TIdHTTP, TIdFTP, etc. What is the correct way to close the connection without raising any exception especially if the server went down before doing so?
I know that all of these classes inherit from TIdTCPClientCustom so there must be a common way to close them on that class level.
The idea here is that I want to create something similar to std::unique_lock, std::unique_ptr, and std::lock_guard. Let's call it unique_connection<T> for instance. So, regardless of the template T which can be any class that inherits from TIdTCPClientCustom, whenever unique_connection goes out of scope it will close the connection without raising any exceptions whether the server is still running or not.
I need this to make sure that there are no resources like sockets, or connections that are still open before the client gets destroyed.
|
|
|
session timeout thread |
Posted by: ebob42 - 03-12-2024, 11:46 AM - Forum: IntraWeb General Discussion
- No Replies
|
|
IntraWeb 15.5.x has made a significant positive change by introducing the TSentinelThread in the ServerController, to watch the internal workings of the session timeout thread activity, and the sentinel thread will restart it when needed. Although there is no way to know for sure (there is no message or output that the TSentinalThread has actually restarted the session timeout thread), we have not encountered situations where sessions were no longer destroyed.
Except... for a relative new situation, where one thread is using 25% CPU (we have 4 -core servers), and it looks like this may be the session timeout thread, since new session can still be created, but older sessions are no longer destroyed. And after a few hours, this leads to hundreds of extra sessions and memory overhead.
Could it be that the session timeout thread is locking some resource, and waiting for another reasons to become available? In other words, could this be a deadlock situation?
The next time this happens, I will attempt to kill the thread that takes 25% CPU. If this is indeed the session timeout thread, then hopefully the sentinel thread will restart it (although this will leave the locked resources probably still locked, so there's a big chance we'll end up in the same deadlock situation again.
If you have anything that could help us pinpoint or resolve this problem, we would be very grateful. Thanks.
Groetjes, Bob Swart
|
|
|
IntraWeb 15.5.8 TIWRegion Showing as white |
Posted by: CharCoil - 03-09-2024, 07:26 PM - Forum: IntraWeb General Discussion
- No Replies
|
|
IntraWeb 15.5.8 TIWRegion Showing as white even when set to other color. This issue only effecting design as the color does take effect for actual application but the designer always showing the background as white. I just upgrade from 1.5.3.1 to 15.5.8 and ran into this issue. This issue even applies with creating a new project and placing IWRegion on the form and changing color.
I try this in Delphi 11.3 but also test it in Delphi EX2 and the same thing.
|
|
|
Multipage websocket communication |
Posted by: davidbaxter - 03-08-2024, 09:31 PM - Forum: IntraWeb General Discussion
- Replies (1)
|
|
I've a Delphi 12 VCL app that I'm using Intraweb and sgcWebsockets to develop a web page based remote control for. Use a browser to control the app as you would as if you were at the computer sort of thing. To make the web pages nice for iPhones and such, it requires 2 pages. I put a websocket server in the VCL app and a client on the first page of the Intraweb app. Works great. Buttons work, data flows back and forth. The problem comes when the web app is switched to the second page. The client on the first page disconnects. Adding a second client to the second page doesn't connect either. Tried adding a second server with diffferent port numbers on the VCL without success. I'm using the two page design outlined in the Intraweb 15 example "MultiPageAPP". How can I get both pages to 'talk'?
|
|
|
|