Chilkat HOME .NET Core C# Android™ AutoIt C C# C++ Chilkat2-Python CkPython Classic ASP DataFlex Delphi ActiveX Delphi DLL Go Java Lianja Mono C# Node.js Objective-C PHP ActiveX PHP Extension Perl PowerBuilder PowerShell PureBasic Ruby SQL Server Swift 2 Swift 3,4,5... Tcl Unicode C Unicode C++ VB.NET VBScript Visual Basic 6.0 Visual FoxPro Xojo Plugin
(SQL Server) Bidirectional Sockets (TLS or non-TLS, simultaneous reading and writing a connection)This example demonstrates how to simultaneously read/write on a single socket connection.
-- Important: See this note about string length limitations for strings returned by sp_OAMethod calls. -- CREATE PROCEDURE ChilkatSample AS BEGIN DECLARE @hr int DECLARE @iTmp0 int DECLARE @iTmp1 int -- Important: Do not use nvarchar(max). See the warning about using nvarchar(max). DECLARE @sTmp0 nvarchar(4000) -- This example requires the Chilkat API to have been previously unlocked. -- See Global Unlock Sample for sample code. DECLARE @tlsRead int -- Use "Chilkat_9_5_0.Socket" for versions of Chilkat < 10.0.0 EXEC @hr = sp_OACreate 'Chilkat.Socket', @tlsRead OUT IF @hr <> 0 BEGIN PRINT 'Failed to create ActiveX component' RETURN END -- We'll just use an HTTPS server for this example... DECLARE @bUseTls int SELECT @bUseTls = 1 DECLARE @maxWaitMs int SELECT @maxWaitMs = 5000 DECLARE @success int EXEC sp_OAMethod @tlsRead, 'Connect', @success OUT, 'www.chilkatsoft.com', 443, @bUseTls, @maxWaitMs IF @success <> 1 BEGIN EXEC sp_OAGetProperty @tlsRead, 'LastErrorText', @sTmp0 OUT PRINT @sTmp0 EXEC @hr = sp_OADestroy @tlsRead RETURN END -- Chilkat classes are thread-safe. This means that only one method call can be active -- at a time for a given object instance. It would seem that this would prevent the possibility -- to simultaneously read/write a given connection because it would require two method calls -- to be simultaneously active: one for reading and one for writing. -- -- There's a trick to doing it... -- -- The CloneSocket method is provided to get a new object instance that shares the same socket -- connection. This allows for the coarse-grained object-level thread safety to be maintained, -- while finer-grained thread-safety mechanisms keep things kosher internally. -- One object will be used for reading, and the cloned socket is used for writing. -- It doesn't matter which -- you can use the cloned socket for reading or the original for writing. -- However.. if you try to read simultneously from both the original and cloned objects at the same -- time, then one will block until the other finishes. (This is because of the finer-grained thread -- safety internally.) The same is true if you try to write both socket objects simultaneously. DECLARE @tlsWrite int EXEC sp_OAMethod @tlsRead, 'CloneSocket', @tlsWrite OUT -- Let's start an async read on the socket. Nothing will be arriving until we actually send the GET -- request and the server responds. This will read until the end of the HTTP response header. DECLARE @task int EXEC sp_OAMethod @tlsRead, 'ReceiveUntilMatchAsync', @task OUT, CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10) EXEC sp_OAMethod @task, 'Run', @success OUT -- Now send the request. This should not block because the read is happening on the tlsRead object. DECLARE @httpGetReq nvarchar(4000) SELECT @httpGetReq = 'GET / HTTP/1.1' + CHAR(13) + CHAR(10) + 'Host: www.chilkatsoft.com' + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10) EXEC sp_OAMethod @tlsWrite, 'SendString', @success OUT, @httpGetReq -- Assuming success for the example... -- Wait for the read task to finish. -- The 1/0 returned by Wait applies to the Wait method call, not the task. SELECT @maxWaitMs = 5000 EXEC sp_OAMethod @task, 'Wait', @success OUT, @maxWaitMs EXEC sp_OAGetProperty @task, 'StatusInt', @iTmp0 OUT EXEC sp_OAGetProperty @task, 'TaskSuccess', @iTmp1 OUT IF Not @success or (@iTmp0 <> 7) or (@iTmp1 <> 1) BEGIN IF Not @success BEGIN -- The task.LastErrorText applies to the Wait method call. EXEC sp_OAGetProperty @task, 'LastErrorText', @sTmp0 OUT PRINT @sTmp0 END ELSE BEGIN -- The ResultErrorText applies to the underlying task method call (i.e. the Connect) EXEC sp_OAGetProperty @task, 'Status', @sTmp0 OUT PRINT @sTmp0 EXEC sp_OAGetProperty @task, 'ResultErrorText', @sTmp0 OUT PRINT @sTmp0 END EXEC @hr = sp_OADestroy @task EXEC @hr = sp_OADestroy @tlsWrite EXEC @hr = sp_OADestroy @tlsRead RETURN END -- Examine the received HTTP response header: PRINT 'HTTP response header:' EXEC sp_OAMethod @task, 'GetResultString', @sTmp0 OUT PRINT @sTmp0 -- We should get a response that looks like this: -- HTTP response header: -- HTTP/1.1 200 OK -- Cache-Control: private -- Content-Length: 7477 -- Content-Type: text/html -- Server: Microsoft-IIS/8.5 -- Set-Cookie: ASPSESSIONIDSWDSTRTQ=BBNMIKGCHFJNILFFPLDIOGDE; secure; path=/ -- X-Powered-By: ASP.NET -- X-Powered-By-Plesk: PleskWin -- Date: Thu, 06 Apr 2017 12:03:30 GMT EXEC @hr = sp_OADestroy @task EXEC @hr = sp_OADestroy @tlsWrite -- Forget about the remainder of the HTTP response... The example was only to demonstrate -- simultaneous reading/writing.. SELECT @maxWaitMs = 20 EXEC sp_OAMethod @tlsRead, 'Close', @success OUT, @maxWaitMs EXEC @hr = sp_OADestroy @tlsRead END GO |
© 2000-2024 Chilkat Software, Inc. All Rights Reserved.