类 workbooks 的 open 方法无效_Tomcat NIO(10)IO线程关键类

在上一篇文章里我们主要介绍了 tomcat io 线程的 overall 调用流程以及关键类SocketProcessor 和 ConnectionHandler 的核心逻辑总结,这里我们主要来介绍剩余其它的核心类 AbstractProcessorLight,Http11Processor,CoyoteAdapter。

AbstractProcessorLight核心逻辑如下:

public SocketState process(SocketWrapperBase> socketWrapper, SocketEvent status) throws IOException {
        SocketState state = SocketState.CLOSED;    Iterator dispatches = null;    do {
            if (dispatches != null) {
                DispatchType nextDispatch = dispatches.next();            state = dispatch(nextDispatch.getSocketStatus());        } else if (status == SocketEvent.DISCONNECT) {
                // Do nothing here, just wait for it to get recycled        } else if (isAsync() || isUpgrade() || state == SocketState.ASYNC_END) {
                state = dispatch(status);            if (state == SocketState.OPEN) {
                    // There may be pipe-lined data to read. If the data isn't                // processed now, execution will exit this loop and call                // release() which will recycle the processor (and input                // buffer) deleting any pipe-lined data. To avoid this,                // process it now.                state = service(socketWrapper);            }        } else if (status == SocketEvent.OPEN_WRITE) {
                // Extra write event likely after async, ignore            state = SocketState.LONG;        } else if (status == SocketEvent.OPEN_READ){
                state = service(socketWrapper);        } else {
                // Default to closing the socket if the SocketEvent passed in            // is not consistent with the current state of the Processor            state = SocketState.CLOSED;        }        if (getLog().isDebugEnabled()) {
                getLog().debug("Socket: [" + socketWrapper + "], Status in: [" + status + "], State out: [" + state + "]");        }        if (state != SocketState.CLOSED && isAsync()) {
                state = asyncPostProcess();            if (getLog().isDebugEnabled()) {
                    getLog().debug("Socket: [" + socketWrapper + "], State after async post processing: [" + state + "]");            }        }        if (dispatches == null || !dispatches.hasNext()) {
                dispatches = getIteratorAndClearDispatches();        }    } while (state == SocketState.ASYNC_END || dispatches != null && state != SocketState.CLOSED);    return state;}
  • 该类的核心方法为 process() ,会被在上一篇文章之中介绍的 ConnectionHandler 对象实例的 process() 方法调所用。
  • 该方法根据不同的 socket 事件和是否采用异步处理来进行不同的调用,返回期望的 SocketState 状态,这里我们只对非异步的正常调用介绍。
  • 对于非异步的正常调用下,SocketEvent 为 OPEN_READ ,进入Http11Processor 实例的 service() 方法。
  • 对于其他未知的 SocketEvent 事件来说,返回给 ConnectionHandler 实例的SocketState 为 CLOSED 。根据以前文章,这样的结果会被给 SocketProcessor 关闭原始 socket 。

Http11Processor的核心代码逻辑如下:

public AbstractProcessor(Adapter adapter) {
         this(adapter, new Request(), new Response());}//Http11Processorpublic Http11Processor(AbstractHttp11Protocol> protocol, Adapter adapter) {
        super(adapter);    this.protocol = protocol;    httpParser = new HttpParser(protocol.getRelaxedPathChars(),            protocol.getRelaxedQueryChars());    inputBuffer = new Http11InputBuffer(request, protocol.getMaxHttpHeaderSize(),            protocol.getRejectIllegalHeaderName(), httpParser);    request.setInputBuffer(inputBuffer);    outputBuffer = new Http11OutputBuffer(response, protocol.getMaxHttpHeaderSize());    response.setOutputBuffer(outputBuffer);    // Create and add the identity filters.    inputBuffer.addFilter(new IdentityInputFilter(protocol.getMaxSwallowSize()));    outputBuffer.addFilter(new IdentityOutputFilter());    // Create and add the chunked filters.    inputBuffer.addFilter(new ChunkedInputFilter(protocol.getMaxTrailerSize(),            protocol.getAllowedTrailerHeadersInternal(), protocol.getMaxExtensionSize(),            protocol.getMaxSwallowSize()));    outputBuffer.addFilter(new ChunkedOutputFilter());    // Create and add the void filters.    inputBuffer.addFilter(new VoidInputFilter());    outputBuffer.addFilter(new VoidOutputFilter());    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DISPID_WORKBOOKS_OPEN 不是一个方法,而是一个常量,用于标识 Microsoft Excel 应用程序对象模型中的 Workbooks_Open 事件的 ID。而 Workbooks_Open 事件是由 Excel 触发的,在 Workbooks 集合中打开一个新工作簿时会触发该事件,可以通过 OLE/COM 自动化技术来捕获该事件,并执行相应的操作。 下面是一个使用 C 语言实现 Workbooks_Open 事件处理程序的示例代码: ``` #include <windows.h> #include <ole2.h> #include <ocidl.h> #include <excel.h> // 定义 Workbooks_Open 事件的标识符常量 const DISPID DISPID_WORKBOOKS_OPEN = 0x0000061D; // 定义 WorkbookEvents 接口的 GUID const IID IID_IWorkbookEvents = {0x00024412, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}; // 定义 WorkbookEvents 接口的方法 interface WorkbookEvents : IDispatch { virtual HRESULT STDMETHODCALLTYPE Open(IDispatch* Workbook) = 0; }; // 定义 WorkbookEvents 接口的 VTable WorkbookEventsVtbl VTable_WorkbookEvents = { // IDispatch 方法 ... // WorkbookEvents 方法 WorkbookEvents_Open }; // 定义 WorkbookEvents 接口的实现 class WorkbookEventsImpl : public WorkbookEvents { public: // IDispatch 方法的实现 ... // WorkbookEvents 方法的实现 HRESULT STDMETHODCALLTYPE Open(IDispatch* Workbook) { // 处理 Workbooks_Open 事件 // 获取 Workbook 的名称 VARIANT Result; DISPID DispID; DISPPARAMS DispParams = {0}; DispID = 0; DispParams.cArgs = 0; DispParams.rgvarg = NULL; Workbook->Invoke(DispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &DispParams, &Result, NULL, NULL); BSTR bstrName = Result.bstrVal; // 在控制台输出 Workbook 名称 wprintf(L"Workbook %s is opened.\n", bstrName); return S_OK; } }; // 订阅 Workbooks_Open 事件 void SubscribeWorkbooksOpenEvent(IDispatch* Excel) { // 获取 Excel 的 Application 对象 IDispatch* Application; Excel->QueryInterface(IID_IDispatch, (void**)&Application); // 获取 Application 的 Workbooks 对象 IDispatch* Workbooks; VARIANT Result; DISPID DispID; DISPPARAMS DispParams = {0}; DispID = DISPID_PROPERTYPUT; DispParams.cArgs = 1; DispParams.rgvarg = &Result; VariantInit(&Result); Result.vt = VT_BSTR; Result.bstrVal = SysAllocString(L"Workbooks"); Application->Invoke(DispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &DispParams, &Workbooks, NULL, NULL); // 获取 Workbooks 的 ConnectionPointContainer 对象 IConnectionPointContainer* ConnectionPointContainer; Workbooks->QueryInterface(IID_IConnectionPointContainer, (void**)&ConnectionPointContainer); // 获取 ConnectionPointContainer 的 ConnectionPoint 对象 IConnectionPoint* ConnectionPoint; ConnectionPointContainer->FindConnectionPoint(IID_IWorkbookEvents, &ConnectionPoint); // 创建 WorkbookEventsImpl 对象 WorkbookEventsImpl* pWorkbookEventsImpl = new WorkbookEventsImpl(); // 建立 ConnectionPoint 和 WorkbookEventsImpl 之间的连接 DWORD dwCookie; ConnectionPoint->Advise(pWorkbookEventsImpl, &dwCookie); } ``` 在上面的示例代码中,我们定义了 DISPID_WORKBOOKS_OPEN 常量、IID_IWorkbookEvents 接口的 GUID 和 WorkbookEvents 接口的方法和 VTable,以及 WorkbookEventsImpl 类的实现。在 SubscribeWorkbooksOpenEvent 函数中,我们订阅了 Workbooks_Open 事件,并建立 ConnectionPoint 和 WorkbookEventsImpl 之间的连接。在 WorkbookEventsImpl::Open 方法中,我们获取了 Workbook 的名称,并在控制台输出该名称。可以根据具体需求来编写相应的 Workbooks_Open 事件处理代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值