注册 登录
编程论坛 VFP论坛

重点介绍“Netsuite.DLL V1.05”的几个函数

iswith 发布于 2023-09-19 07:52, 538 次点击
*RSA------------
      *注意错误会直接抛出
      Local loRSA      ;
            , lnKeySize;
            , xml         ;
            , pem_pkcs1;
            , pem_pkcs8
            
      *从DLL中获取RSA
      m.lnKeySize = 512 &&1024
      m.loRSA       = oFunction.GetRSA( m.lnKeySize )
      Clear
      ?Transform(lnKeySize) + '私钥(xml):'
       xml = m.loRSA.ToXML()
      ??xml
      ?Transform(lnKeySize) + '私钥(PKCS#1):' &&用于解密(加密需要私钥需要最强大的第三方DLL....)
       pem_pkcs1 = m.loRSA.ToPEM().ToPEM_PKCS1()
      ?pem_pkcs1
      ?Transform(lnKeySize) + '公钥(PKCS#8):' &&用于加密
       pem_pkcs8 = m.loRSA.ToPEM().ToPEM_PKCS8()
      ?pem_pkcs8
      ?'RSA待加密字符串:'
        m.lcstr =  'Netsuite.Function For ZHZ V1.0'  
      ??m.lcstr
      ?'RSA加密:'
        Local lcenstr
        m.lcenstr = m.loRSA.Encode( m.lcstr )
      ??m.lcenstr
      ?'RSA解密:'
        m.lcdestr = m.loRSA.DecodeOrNull( m.lcenstr)
      ??m.lcdestr
      
      ?'签名SHA1:'
        Local lcsign
        m.lcsign = m.loRSA.Sign("SHA1", m.lcstr )
        ??m.lcsign
      *m.loRSA.Sign("SHA224", m.lcstr )没有,以后再补
      *m.loRSA.Sign("SHA256", m.lcstr )有
      *m.loRSA.Sign("SHA384", m.lcstr )没有,以后再补
      *m.loRSA.Sign("SHA512", m.lcstr )没有,以后再补
      *m.loRSA.Sign("SHA3"  , m.lcstr )没有,以后再补     
      ??m.lcsign
      ?'校验签名:'
      ??m.loRSA.Verify("SHA1", m.lcsign, m.lcstr)
      
      
      *用pem文本创建RSA
      Local loRSA2
      m.loRSA2= oFunction.GetRSA2( pem_pkcs8 )
      ?'用PEM公钥(PKCS#8)新创建的RSA是否和上面的一致:'
      ?'XML:'
      ??m.loRSA2.ToXML() == m.loRSA.ToXML()
      ?'PKCS1:'
      ??m.loRSA2.ToPEM().ToPEM_PKCS1() == m.loRSA.ToPEM().ToPEM_PKCS1()
      ?'PKCS8:'
      ??m.loRSA2.ToPEM().ToPEM_PKCS8() == m.loRSA.ToPEM().ToPEM_PKCS8()


      *用xml文本创建RSA
      Local loRSA3
      m.loRSA3= oFunction.GetRSA3( xml )
      ?'用xml文本新创建的RSA是否和上面的一致:'
      ?'XML:'
      ??m.loRSA3.ToXML() == m.loRSA.ToXML()
      ?'PKCS1:'
      ??m.loRSA3.ToPEM().ToPEM_PKCS1() == m.loRSA.ToPEM().ToPEM_PKCS1()
      ?'PKCS8:'
      ??m.loRSA3.ToPEM().ToPEM_PKCS8() == m.loRSA.ToPEM().ToPEM_PKCS8()


*--声音播放函数(异步线程(默认) )
      *--载入H文件
      #INCLUDE Netsuite.H
      
      Local loDevice ;
            , lisTask  ;
            , lcFileName
      
      m.lcFileName = Getfile("mp3,wav")
      m.lisTask    = .T.
      If Empty( m.lcFileName ) Then
         Return
      Endif  
      
      *--播放声音
      *m.oFunction.MmPaly( cFile, lisTask ) &&可以异步,同步
      *cFile     必传   文件路径
      *lisTask  非必传 默认.T.异步线程|.F. 同步线程
      m.loDevice   = m.oFunction.MmPaly( m.lcFileName , m.lisTask )
      *--判定
      ?"已停止:"   + Transform( m.loDevice.PlaybackState = Stopped  )
      ?"正在播放:" + Transform( m.loDevice.PlaybackState = Playing  )
      ?"暂停中:"   + Transform( m.loDevice.PlaybackState = Paused   )

      *--动作
*!*      m.loDevice.Play() &&播放
*!*      m.loDevice.Pause()&&暂停
*!*      m.loDevice.Stop    &&停止
      
      *--文本转语音播报(默认异步线程),其实就是Edge的大声朗读,遗憾C# WebSocket不支持Win7平台
      *m.oFunction.Say( string str,string voice,string outfilename ="say.mp3", bool isTask = true)
      *str               必传    文本
      *voice         非必传  哪个M播音员 默认 "zh-CN-XiaoxiaoNeural"
      *OutFileName      非必传  输出音频 默认DLL所在目录下say.mp3
      *isTask          非必传  默认.T.异步线程|.F. 同步线程
      oSay = m.oFunction.Say("今天天气真他妈热啊!")

[此贴子已经被作者于2023-9-19 11:44编辑过]

6 回复
#2
iswith2023-09-19 11:35
*--需要Netsuite.dll V1.05版支持(WebSocketsServer DLL 多线程同步,可高并,VFP 单线程 )
*--不依赖于HttpListener或HTTP.sys意味着他将在Windows 7和Server 2008主机上运行

*--说明:实现了双向通信,可以让服务端向客户端进行主动发起通信;
         不仅仅可以实现点对点的通信,;
         同时还可以实现群聊的形式。可以通过一定的逻辑;
         将用户发出的信息在服务端进行组播,从而实现同一聊天室内的多人通信
         
         
        *可以使用wss安全协议服务,需要证书
         
        *WebsocketServer事件化且绑定了events.prg 类“WebSocketsEvents”的委托方法,如 OnMessage,祥请查看“events.prg”
        
*--websocket_html5test.html 用于Web模拟Client端H5测试
*--websocket_htmlJstest        用于Web模拟Client端Js测试

Clear

If _vfp.StartMode = 0 Then
   m.lcPath = Justpath( _vfp.ActiveProject.Name  )
Else
   m.lcPath = Justpath( sys(16,0) )
Endif   
 
Set Default To ( m.lcPath )

*--载入WebSocket事件
Set Procedure To Events.prg , netsuite.reg.prg Additive

Public oWebSocketsServer
m.oWebSocketsServer = Createobjects( "Netsuite.WebSockets")

Local lcUrl            ;
    , lcpfxFilePath ;
    , lcpfxPassword
   
m.lcUrl          = "ws://0.0.0.0:30000" &&"wss://0.0.0.0:30000"

*Start(string cUrl , string pfxFilePath ="", string pfxPassword = "")
    * pfxFilePath 非必传 只有Url为Wss使用证书路径
    * pfxPassword 非必传 只有Url为Wss使用证书密码

m.oWebSocketsServer.Start( "ws://0.0.0.0:30000" )


public  loServer
m.loServer = oWebSocketsServer.Server
With m.loServer
    ?.Location
    ?.Port
    ?.SupportDualStack
    ?.ListenerSocket.Connected
    ?.EnabledSslProtocols
    ?.SupportDualStack
Endwith

With m.oWebSocketsServer
    * .Send( String ClientID , String Msg)  发送信息                 &&return bool .T. 成功|.F.失败
    * .CloseAllConnect()                      关闭所有Client连接
    * .CloseUserConnect( ClientID)           关闭对应的Client连接    &&return bool .T. 成功|.F.失败
    * .GetConnectList()                        获取已连接的Client列表  &&return Client1\nClinet2\n......
    * .Dispose()                            垃圾回收
    * .CloseServer()                        关闭服务
    * oSocket = GetUserSocketInstance( String ClientID )             &&return objects .T.获取用户实例|.F. null
        * oSocket IDE支持可以oSocket.查看Socket对象的方法属性
Endwith

Local loWebSocketsEvents
m.loWebSocketsEvents = CREATEOBJECT("WebSocketsEvents")

If !EVENTHANDLER( m.oWebSocketsServer , m.loWebSocketsEvents ) Then
    Messagebox('绑定WebSocketsEvents类失败!',16, '绑定')
    Return .F.
Endif

*--------WebSocketsEvents----------------------
Define Class WebSocketsEvents AS Custom OLEPUBLIC
      
       Implements WebSocketsEvents IN "Netsuite.WebSockets"      
       *--连接时
       Procedure WebSocketsEvents_OnOpen( ip as String)
                   ?'连接:'+ m.ip
       Endproc

       *--关闭时      
       Procedure WebSocketsEvents_OnClose( ip as String)
                ?'关闭:'+ m.ip
       Endproc

       *--收到消息   
       Procedure WebSocketsEvents_OnMessage( cid as string, ip as String , msg as String )
                ?' 收到消息:' + m.ip
                ??Space(4) + m.msg
       Endproc

       *--收到二进制信息     
       Procedure WebSocketsEvents_OnBinary( Length as Integer , Byte as Byte )
                ?'收到二进制信息长度:' + Transform( m.Length  )
                ??Space(4) + strconv( m.Byte , 9 )
       Endproc

       *--异常信息   
       Procedure WebSocketsEvents_OnError( cid as string ,HResult as Integer , Message as string , Source as string , StackTrace as string )
                ?'异常信息:'   + m.cid
                ?'Result:'     + Transform( m.HResult )
                ?'Message:'    + m.Message
                ?'Source:'     + m.Source
                ?'StackTrace:' + m.StackTrace
       Endproc

EndDefine


[此贴子已经被作者于2023-9-19 11:36编辑过]

#3
iswith2023-09-19 11:39
*--需要Netsuite.dll V1.05版支持(WebSocketsServer DLL 异步多线程,高并,VFP STA单元 单线程 )
*--不依赖于HttpListener或HTTP.sys意味着他将在Windows 7和Server 2008主机上运行
*--使用安全的网络通讯协议 (wss://)
*--已添加检测设置心跳,Client列表自动维护

*--Websocket_htmljstest.html 用于Web模拟Client端测试

_vfp.AutoYield = .F.

Clear

If _vfp.StartMode = 0 Then
   m.lcPath = Justpath( _vfp.ActiveProject.Name  )
Else
   m.lcPath = Justpath( sys(16,0) )
Endif   
 
Set Default To ( m.lcPath )

Set Procedure To netsuite.reg.prg Additive

Do win_api

*--创建PRG处理器
*--当DLL创建的WebSocketServer服务收到Client的消息时由VFP创建的PRG生成的FXP进行应答;
   FXP应答线程模式为:(STA)单元线程,在处理器FXP应答处理VFP信息加工时,它可以被动态执换;
   可以按条件去执行不同的函数进行处理,该特性由ProcessorFilename|Cmd 来控制。注意每次函数;
   处理都需要Return "处理得到的信息",将视为发送给Client的应答信息,MSG-请求信息,Return-应答信息;
   MSg 可以多样形式的字符串如cjson ,credis,那么FXP就需要相应的解析来处理什么的请求信息做怎样的应答。
   
Erase  ( Addbs( Getenv("TEMP") ) + '*.prg' )

Local lcCreateprgFilename;   
    , lcProcessorFilename;
     ,lcthrFunction        
   
m.lcCreateprgFilename    = Addbs( Getenv("TEMP") ) + Sys(2015) + '.prg'   
m.lcProcessorFilename    = Forceext( m.lcCreateprgFilename, 'fxp' ) &&线程执行的VFP过程函数*--创建线程函数

Text To m.lcthrFunction Textmerge noShow
   
    Function processor( IP         As String ;
                      , Msg     As String )
                       
             Do win_api
            
             Local lcReturn
             Do Case
               
                Case Alltrim( m.Msg ) =='test1'
                     Sleep(10*1000)
                     m.lcReturn  = [{"PRG处理器过程processor,自我阻塞3*1000秒"}]
                     
                Case Alltrim( m.Msg ) =='test2'
                     m.lcReturn  = [{"PRG处理器过程processor,自我不阻塞"}]
                 
                 Otherwise
                 
                      m.lcReturn  = [{"] + m.Msg + ["}]
             Endcase
            
             Return m.lcReturn
            
    Endfunc
   
Endtext


strtofile( lcthrFunction , m.lcCreateprgFilename )
Compile ( m.lcCreateprgFilename )
Erase  ( m.lcCreateprgFilename )
If !File( m.lcProcessorFilename ) Then
    Messagebox('WebSocketServer.prg处理器未创建成功!' ,16 )
    Return  
Endif

*--实例化oWebSocketsServer2
Public oWebSocketsServer2
m.oWebSocketsServer2                 = Createobjects( "Netsuite.WebSockets2" )

Local lcUrl            ;
    , lcpfxFilePath ;
    , lcpfxPassword
   
m.lcUrl          = "ws://0.0.0.0:30000" &&"wss://0.0.0.0:30000"
*Start(string cUrl , string pfxFilePath ="", string pfxPassword = "")
    * pfxFilePath 非必传 只有Url为Wss使用证书路径,注意服务也需要配置
    * pfxPassword 非必传 只有Url为Wss使用证书密码,注意服务也需要配置


With m.oWebSocketsServer2
    .ProcessorFilename = m.lcProcessorFilename &&PRG应答处理器的FXP文件动态载入,中途可换
    .Cmd                = [processor(IP,Msg)]  &&执行PRG应答函数
Endwith

*oWebSocketsServer2是异步多线程池管理,并不是同步线程,这里添加阻塞函数等待它全部启动
*该模块应该与VFP的MTCOMDLL多线程对应,DLl中的Server是线程池,但VFP9R.DLL还单一的线程,需要使用
*VFP9T.DLL的多线程构造你的多线应用。
?"线程池启动WebSocketServer"
m.oWebSocketsServer2.Start( m.lcUrl )

Sleep(1*1000)




#4
schtg2023-09-19 14:33
谢谢!
#5
sych2023-09-19 20:04
不如搞个专辑过瘾
#6
kangss2023-09-21 19:25
回复 楼主 iswith
谢谢!

[此贴子已经被作者于2023-9-21 19:39编辑过]

#7
asdf_1230002023-10-09 16:24
1